2013-07-23 2 views

ответ

10

Очень похоже на @ Батист Ответим

> ind <- which(is.na(df), arr.ind=TRUE) 
> df[ind] <- rowMeans(df, na.rm = TRUE)[ind[,1]] 
+1

+1 хорошее использование часто заданного аргумента' arr.ind' –

+0

Я обнаружил, что если у меня есть целые строки NA, возникает ошибка. Правильно ли этот этикет представляет собой совершенно новый вопрос? – Brian

2

Мое решение

rwmns = rowMeans(df,na.rm=TRUE) 
df$c1[is.na(df$c1)] = rwmns[is.na(df$c1)] 
df$c2[is.na(df$c2)] = rwmns[is.na(df$c2)] 
df$c3[is.na(df$c3)] = rwmns[is.na(df$c3)] 
> df 
    c1 c2 c3 
1 1 3 2 
2 2 1 1 
3 3 3 3 
4 2 3 1 

Есть ли более элегантный способ, особенно когда у кого-то много столбцов?

+4

Отличная работа идет с вашим собственным решением. Вы можете использовать '[[' вместо индекса, поэтому каждая строка будет 'df [[col_name]] [is.na (df [[col_name]])] <- rwmns [is.na (df [[col_name]]) '. Таким образом, вы можете создать цикл или использовать семейство apply над именами столбцов, которые вы хотите выполнить. – Justin

4

Я думаю, что это работает,

df[which(is.na(df), arr.ind=TRUE)] <- rowMeans(df[!complete.cases(df), ], na.rm=TRUE) 
+0

+1 приятное решение !! Гораздо лучше, чем моя ленивая «подавать»! –

+0

Это немного избыточно, чтобы использовать как is.na, так и complete.cases; вероятно, более эффективный способ в двух строках – baptiste

+1

Как это возможно? 'idx <- который (is.na (df), arr.ind = TRUE); df [idx] <- rowMeans (df [idx [, 1],], na.rm = TRUE) ' –

3

Использование apply (обратите внимание, что возвращаемый объект является matrix):

t(apply(df , 1 , function(x) { x[ is.na(x) ] = mean(x , na.rm = TRUE); x })) 
    c1 c2 c3 
[1,] 1 3 2 
[2,] 2 1 1 
[3,] 3 3 3 
[4,] 2 3 1 

Мы используем любую анонимную функцию для изменения значения каждого NA в каждой строке к mean этой строки. Единственное преимущество заключается в том, что вам больше не нужно вводить текст, если количество строк увеличивается. Это не особенно эффективно или быстро в вычислительном смысле, но тем более в когнитивном смысле (вы не заметите, если у вас нет 000 000 строк).

2

Другой вариант na.aggregate из library(zoo) после транспонирования набора данных

library(zoo) 
df[] <- t(na.aggregate(t(df))) 
df 
# c1 c2 c3 
#1 1 3 2 
#2 2 1 1 
#3 3 3 3 
#4 2 3 1 
Смежные вопросы