2013-05-30 5 views
28

Вот простой кадр данных с отсутствующим значением:NA значения и R агрегатная функция

M = data.frame(Name = c('name','name'), Col1 = c(NA,1) , Col2 = c(1,1))

Когда я применяю агрегат М следующим образом:

aggregate(.~Name, M, FUN=sum, na.rm=TRUE)

результат является:

RowName Col1 Col2 
name 1 1 

Таким образом, Первая строка ire игнорируется. Но если я

aggregate(M[,2:3], by=list(M$Name), FUN=sum, na.rm=TRUE)

результат

Group.1 Col1 Col2 
name 1 2 

Так только (1,1) запись игнорируется.

Это вызвало серьезную головную боль отладки в одном из моих кодов, поскольку я думал, что эти два вызова эквивалентны. Есть ли веская причина, почему метод ввода «формула» обрабатывается по-разному?

Спасибо.

ответ

34

Хороший вопрос, но, на мой взгляд, это не должно приводить к отладке головной боли основных, поскольку она достаточно четко документирована в нескольких местах на странице руководства для aggregate.

Во-первых, в разделе использования:

## S3 method for class 'formula' 
aggregate(formula, data, FUN, ..., 
      subset, na.action = na.omit) 

Позже, в описании:

na.action: функция, которая указывает на то, что должно произойти, когда данные содержат НС значения. По умолчанию следует игнорировать отсутствующие значения в данных переменных.


Я не могу ответить, почему режима формулы был написан по-другим --- это то, что авторы функции должны отвечать --- но используя приведенную выше информацию, вы, вероятно, можете использовать следующий :

aggregate(.~Name, M, FUN=sum, na.rm=TRUE, na.action=NULL) 
# Name Col1 Col2 
# 1 name 1 2 
+4

-1 для фи Первое предложение (конечно, теперь легко выглядеть, что вы точно знаете, что ищете, но это было бы довольно нетривиально, чтобы найти irl) – eddi

+2

@eddi, без проблем. Я знаю из вашей истории чатов и комментариев, что вам нравятся функции для работы, как вы хотите, а не как они документированы, и вы полностью открыты для этого мнения. – A5C1D2H2I1M1N2O1R2T1

+3

@eddi - Действительно, нисходящий для этого? Я думаю, что Ананда делает там стоящую точку ... Тщательное прочтение справки, скорее, чем позже, - очень хорошая привычка учиться и спасет много головных болей по дороге! –

13

Если вы хотите формулу версия эквивалентной попробовать это:

M = data.frame(Name = rep('name',5), Col1 = c(NA,rep(1,4)) , Col2 = rep(1,5)) 
aggregate(. ~ Name, M, function(x) sum(x, na.rm=TRUE), na.action = na.pass) 
+4

+1, но анонимная функция не требуется: 'aggregate (. ~ Name, M, FUN = sum, na.rm = TRUE, na.action =" na.pass ")' работает тоже. – A5C1D2H2I1M1N2O1R2T1

+1

Спасибо за указание 'na.pass'. Это немного яснее, чем «NULL» (хотя оба, похоже, работают). –

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