2015-06-26 3 views
3

У меня есть блок данных с столбцами данных с отсутствующим значением, и я хотел бы заменить отсутствующее значение, взяв среднее значение, используя значения ячеек выше и ниже.замена отсутствующего значения в R со средним значением

df1<-c(2,2,NA,10, 20, NA,3) 
if(df1[i]== NA){ 
df1[i]= mean(df1[i+1],df1[i-1]) 
} 

Однако, я получаю эту ошибку

Error in if (df1[i] == NA) { : missing value where TRUE/FALSE needed 
    In addition: Warning message: 
    In if (df1[i] == NA) { : 
    the condition has length > 1 and only the first element will be used 

Любое руководство будет оценено, чтобы решить эту проблему.

+1

Что делать, если у вас есть два значения NA в строке? Что делать, если отсутствует первый или последний элемент? – MrFlick

+0

Я использовал df1 в качестве примера, но мой набор данных состоит из тысяч значений, и NA, как установлено, не являются последовательными. – NickWilson

ответ

3

Если вы уверены, что не имеют каких-либо последовательных значений NA и первые и последние элементы никогда не NA, то вы можете сделать

df1<-c(2,2,NA,10, 20, NA,3) 
idx<-which(is.na(df1)) 
df1[idx] <- (df1[idx-1] + df1[idx+1])/2 
df1 
# [1] 2.0 2.0 6.0 10.0 20.0 11.5 3.0 

Это должно быть более эффективным, чем цикл.

+0

Спасибо, это сработало для нас! – NickWilson

1

для проверки использования NA использовать is.na(), сделать цикл и дать mean() вектор в качестве аргумента, иначе он увидит только первое значение. Это должно работать, если у вас нет последовательных Nas и первой и последней записи являются не-NA:

df1<-c(2,2,NA,10, 20, NA,3) 
for(i in 2:(length(df1)-1)){ 
    if(is.na(df1[i])){ 
    df1[i]= mean(c(df1[i+1],df1[i-1])) 
    } 
} 
2

Использование лаг и свинца из dplyr:

library(dplyr) 

df1[is.na(df1)] <- (df1[is.na(lag(df1, default=""))] +   
        df1[is.na(lead(df1, default=""))])/2 

Это будет гораздо быстрее, чем для версии петли

2

Вы можете использовать na.approx() из zoo пакета заменить NA с интерполяцией значений:

library(zoo) 
> na.approx(df1) 
# [1] 2.0 2.0 6.0 10.0 20.0 11.5 3.0 

Как упоминалось в @ G.Grothendieck, это заполнит NA s, если в строке есть несколько NA. Также, если на концах может быть NA s, то добавление аргумента na.rm = FALSE сохранит их или добавит rule = 2 заменит их первым или последним не NA.

+1

Следует отметить, что это решение является единственным, которое заполняет NA, если в строке есть несколько NA. Также, если на концах могут быть NA, то добавление аргумента 'na.rm = FALSE' сохранит их или добавление' rule = 2' заменит их на первый или последний не-NA. –