2013-07-19 4 views
6

У меня есть набор данных, содержащий тестовые данные прототипа продукта. Не все тесты выполнялись на всех лотах, и не все тесты выполнялись с одинаковыми размерами выборки. Для иллюстрации рассмотрит этот случай:Смесь na.omit и na.pass с использованием агрегата?

> test <- data.frame(name = rep(c("A", "B", "C"), each = 4), 
    var1 = rep(c(1:3, NA), 3), 
    var2 = 1:12, 
    var3 = c(rep(NA, 4), 1:8)) 

> test 
    name var1 var2 var3 
1  A 1 1 NA 
2  A 2 2 NA 
3  A 3 3 NA 
4  A NA 4 NA 
5  B 1 5 1 
6  B 2 6 2 
7  B 3 7 3 
8  B NA 8 4 
9  C 1 9 5 
10 C 2 10 6 
11 C 3 11 7 
12 C NA 12 8 

В прошлом, я только должен был иметь дело со случаями MIS-совпадающих повторений, которое было легко с aggregate(cbind(var1, var2) ~ name, test, FUN = mean, na.action = na.omit) (или настройкой по умолчанию). Я получу средние значения для каждого лота по трем значениям для var1 и более четырех значений для var2.

К сожалению, это оставит меня с набором данных полностью отсутствующей много A в этом случае:

aggregate(cbind(var1, var2, var3) ~ name, test, FUN = mean, na.action = na.omit) 
    name var1 var2 var3 
1 B 2 6 2 
2 C 2 10 6 

Если я использую na.pass, однако, я не понимаю, что я хочу:

aggregate(cbind(var1, var2, var3) ~ name, test, FUN = mean, na.action = na.pass) 
    name var1 var2 var3 
1 A NA 2.5 NA 
2 B NA 6.5 2.5 
3 C NA 10.5 6.5 

Теперь я теряю хорошие данные, которые у меня были в var1, так как в нем содержались экземпляры NA.

То, что я хотел бы это:

  • NA как выход mean(), если это всех уникальных комбинаций varN ~ name являются NA сек
  • Выход mean(), если есть один или несколько фактических значений для varN ~ name

Я предполагаю, что это предварительно tty просто, но я просто не знаю, как это сделать. Нужно ли использовать ddply для чего-то вроде этого? Если это так ... поэтому я, как правило, чтобы избежать этого является то, что я в конечном итоге писать действительно длинные эквиваленты aggregate() так:

ddply(test, .(name), summarise, 
    var1 = mean(var1, na.rm = T), 
    var2 = mean(var2, na.rm = T), 
    var3 = mean(var3, na.rm = T)) 

Да ... так что результат того, что, по-видимому делает то, что я хочу. Я оставлю вопрос в любом случае, если есть 1) способ сделать это с помощью aggregate() или 2) более короткий синтаксис для ddply.

+0

Повторно наткнулся на один ответ re. 'ddply' [ЗДЕСЬ] (http://stackoverflow.com/questions/10787640/r-ddply-summarize-with-large-number-of-columns). В принципе, расплавьте фрейм данных, примените 'mean()' на основе комбинаций интересующей переменной и имени предыдущего столбца, а затем верните ее в исходную форму. Любые другие? – Hendy

ответ

16

Pass какna.action=na.pass и na.rm=TRUE к aggregate. Первый говорит aggregate не удалять строки, где существуют NA; и последний говорит mean, чтобы игнорировать их.

aggregate(cbind(var1, var2, var3) ~ name, test, mean, 
      na.action=na.pass, na.rm=TRUE) 
+0

Удивительный, и я понятия не имел, что это возможно. – Hendy

+0

@HongOoi Это сработало отлично. Просто что-то примечание, это заменит НО с нулями в зависимости от выбранной вами функции. Скорее всего, это не окончательный результат, который вам нужен, поэтому просто следите за чем-то вроде 'df [df == 0] <- NA'. Если у вас есть реальные нули в вашем df, которые вы не хотите удалять, тогда скомбинируйте вышеприведенный код с 'is.na (df)' –

+0

, это возвращает 'NaN', а не' NA' для имени 'A', 'var3' – colin

Смежные вопросы