R: Какие функции лучше всего подходят для объединения и усреднения значений в data.frame?

У меня есть data.frame из этого кода:

   my_df = data.frame("read_time" = c("2010-02-15", "2010-02-15", 
                                      "2010-02-16", "2010-02-16", 
                                       "2010-02-16", "2010-02-17"), 
                      "OD" = c(0.1, 0.2, 0.1, 0.2, 0.4, 0.5) )

что производит это:

> my_df
   read_time  OD
1 2010-02-15 0.1
2 2010-02-15 0.2
3 2010-02-16 0.1
4 2010-02-16 0.2
5 2010-02-16 0.4
6 2010-02-17 0.5

Я хочу усреднить столбец OD по каждому отдельному read_time (обратите внимание, что некоторые реплицируются, другие нет), и я также хотел бы вычислить стандартное отклонение, создав такую ​​таблицу:

> my_df
   read_time  OD        stdev
1 2010-02-15 0.15       0.05
5 2010-02-16 0.3         0.1
6 2010-02-17 0.5         0

Какие функции лучше всего подходят для объединения таких значений в data.frame?


person John    schedule 18.03.2010    source источник


Ответы (3)


Пакет plyr популярен для этого, но базовый функции by() и aggregate() также помогут.

> ddply(my_df, "read_time", function(X) data.frame(OD=mean(X$OD),stdev=sd(X$OD)))
   read_time      OD   stdev
1 2010-02-15 0.15000 0.07071
2 2010-02-16 0.23333 0.15275
3 2010-02-17 0.50000      NA

Вы можете добавить недостающий бит, чтобы вернуть 0 вместо NA для последнего std.dev.

Кроме того, вам не нужны кавычки (для переменных), которые были в конструкции data.frame.

person Dirk Eddelbuettel    schedule 18.03.2010
comment
Спасибо, Дирк, это хорошо работает с пакетом plyr, но не могли бы вы сказать мне, как добавить еще один столбец к данным, у меня есть еще один столбец с именем day в моем реальном наборе данных. Я пробовал это: ddply (Individual_well_series_od, read_time, function (X) data.frame (od = mean (X $ od), stdev = sd (X $ od), day = X $ day)), но он возвращает все read_times снова. Я понимаю, что сегодня не применяю функцию, но читаю справку, но не вижу, куда ее поместить. - person John; 19.03.2010
comment
И я попробовал исходный код без даты, но даты не читались правильно, поэтому я сохранил их, я мог бы попытаться преобразовать их в объекты дат, которые, как я полагаю, я сохранил как этот простой пример. - person John; 19.03.2010
comment
Не даты, а переменные, т.е. используйте data.frame (a = 1: 3), а не data.frame (a = 1: 3) Что касается добавления переменной, вы не можете - вызов ddply уменьшает несколько строк в однорядную сводку. Если вы добавите исходный столбец данных, вы получите повторы. Вы должны это обдумать. - person Dirk Eddelbuettel; 19.03.2010
comment
Или со встроенной summarize вспомогательной функцией: ddply(my_df, "read_time", summarise, OD = mean(OD), stdev = sd(OD)) - person hadley; 19.03.2010
comment
резюмировать (с z) или резюмировать (с s) или и то, и другое? ;-) R прекрасно поддерживает британское и американское правописание ... - person Dirk Eddelbuettel; 19.03.2010
comment
спасибо, он тоже отлично работает с суммированием. Я также исправил новые переменные, включив, например, days = unique (дни) - person John; 20.03.2010
comment
Но уникальных (дней) можно было вернуть больше одного. Вы можете попробовать head (days, 1) или даже head (unique (days), 1). - person Dirk Eddelbuettel; 20.03.2010

Вы можете попробовать пакет data.table. Если вы знаете MySQL, вам должно быть очень легко получить все функции, в противном случае основы тоже достаточно хороши ;-)

my_dfdt<-data.table(my_df)
mean<-my_dfdt[,mean(OD), by="read_time"]
sd<-  ..  

вы также можете объединить оба в одну строку или cbind в конце, ваш вызов стиля

Еще одно преимущество: это очень быстро, если у вас большие образцы. Очень быстро ... см. Документацию, почему.

person jorgusch    schedule 19.03.2010

Это иллюстрирует, как вы можете использовать aggregate для получения среднего и стандартного отклонения по вашему read_time.

>aggregate(my_df$OD, by=list(my_df$read_time), function(x) mean(x))

     Group.1         x
1 2010-02-15 0.1500000
2 2010-02-16 0.2333333
3 2010-02-17 0.5000000


>aggregate(my_df$OD, by=list(my_df$read_time), function(x) sd(x))
     Group.1          x
1 2010-02-15 0.07071068
2 2010-02-16 0.15275252
3 2010-02-17         NA
person andrewj    schedule 19.03.2010
comment
Если вы просто хотите, чтобы вызывалась существующая функция, вам не нужно определять свою собственную анонимную функцию. Вы можете передать существующую функцию: aggregate (my_df $ OD, by = list (my_df $ read_time), mean) - person Jyotirmoy Bhattacharya; 19.03.2010