2016-11-11 16 views
0

Вот очень простой пример того, что я имею дело с:Средневзвешенное значение в присутствии NA значения

data_stack <- data.table(CompA_value = c(10,20,30,40), CompB_value = c(60,70,80,80), CompC_value = c(NA, NA, NA, 100), CompA_weight = c(0.2, 0.3,0.4,0.4), CompB_weight = c(0.8,0.7,0.6,0.4), CompC_weight = c(NA, NA, NA,0.2)) 

    CompA_value CompB_value CompC_value CompA_weight CompB_weight CompC_weight 
1:   10   60   NA   0.2   0.8   NA 
2:   20   70   NA   0.3   0.7   NA 
3:   30   80   NA   0.4   0.6   NA 
4:   40   80   100   0.4   0.4   0.2 

То, что я хочу сделать, это рассчитать средневзвешенную COMPA через С, для каждой строки , Однако обратите внимание, что CompC имеет NA для строк 1-3. Я бы хотел, чтобы строки 1-3 имели средневзвешенное значение CompA и CompB, но как только CompC станет активным, я бы хотел, чтобы он автоматически включался в расчет.

Как она стоит, я сделал что-то вроде этого:

> data_stack[, Weighted_average := CompA_value*CompA_weight + CompB_value*CompB_weight + CompC_value * CompC_weight] 
> data_stack 
    CompA_value CompB_value CompC_value CompA_weight CompB_weight CompC_weight Weighted_average 
1:   10   60   NA   0.2   0.8   NA    NA 
2:   20   70   NA   0.3   0.7   NA    NA 
3:   30   80   NA   0.4   0.6   NA    NA 
4:   40   80   100   0.4   0.4   0.2    68 

Но моя колонка «Weighted_average», очевидно, не даст мне веса в течение первых 1-3 рядов.

Что я хочу:

data_stack[, Weighted_average := c((10*0.2 + 60*0.8),(20*0.3 + 70*0.7),(30*0.4 + 80*0.6),(40*0.4 + 80*0.4 + 100*0.2))] 
data_stack 
    CompA_value CompB_value CompC_value CompA_weight CompB_weight CompC_weight Weighted_average 
1:   10   60   NA   0.2   0.8   NA    50 
2:   20   70   NA   0.3   0.7   NA    55 
3:   30   80   NA   0.4   0.6   NA    60 
4:   40   80   100   0.4   0.4   0.2    68 

Итак, обратите внимание, как первые три строки только средневзвешенное значение А и В, но когда C становится доступным, он также включен в расчет.

Итак, я хотел бы узнать, как написать код, который подбирает, есть ли значение NA, если да, то пропускает его, но если оно не включает его в расчет.

У меня есть значительно больший стол данных, поэтому делать это вручную не может быть и речи!

С уважением.

+2

Вы можете заменить все NA на 0 и затем принять средневзвешенное значение. –

+0

Почему бы не попробовать 'data_stack [is.na (data_stack)] <- 0'? – Aramis7d

ответ

1

Здесь вы идете:

data_stack$Weighted_average = apply(data_stack,1,function(x){ 
    y = c(x["CompA_value"]*x["CompA_weight"], 
     x["CompB_value"]*x["CompB_weight"], 
     x["CompC_value"]*x["CompC_weight"]) 
    return(sum(y,na.rm = T)) 
}) 

Результат:

> data_stack 
    CompA_value CompB_value CompC_value CompA_weight CompB_weight CompC_weight Weighted_average 
1   10   60   NA   0.2   0.8   NA    50 
2   20   70   NA   0.3   0.7   NA    55 
3   30   80   NA   0.4   0.6   NA    60 
4   40   80   100   0.4   0.4   0.2    68 

Функция создает вектор со значением * вес для каждого столбца. Затем возвращает сумму, игнорирующую значения NA. Это означает, что это игнорирует значения NA в любом столбце.