2012-05-03 5 views
11

Это, наверное, глупый вопрос, но я прочитал главу Кроули о данных и просмотрел Интернет и еще ничего не смог сделать.Подведение строк на основе конкретных комбинаций факторов

Вот пример набора данных похож на мой:

> data<-data.frame(site=c("A","A","A","A","B","B"), plant=c("buttercup","buttercup", 
"buttercup","rose","buttercup","rose"), treatment=c(1,1,2,1,1,1), 
plant_numb=c(1,1,2,1,1,2), fruits=c(1,2,1,4,3,2),seeds=c(45,67,32,43,13,25)) 
> data 
    site  plant treatment plant_numb fruits seeds 
1 A buttercup   1   1  1 45 
2 A buttercup   1   1  2 67 
3 A buttercup   2   2  1 32 
4 A  rose   1   1  4 43 
5 B buttercup   1   1  3 13 
6 B  rose   1   2  2 25 

То, что я хотел бы сделать, это создать сценарий, в котором «семена» и «плоды» суммируются всякий раз, когда уникальный сайт & завод & лечение & комбинации plant_numb существовать. В идеале, это привело бы к сокращению рядов, но сохранение исходных столбцов (т.е. мне нужно в приведенном выше примере, чтобы выглядеть следующим образом :)

site  plant treatment plant_numb fruits seeds 
1 A buttercup   1   1  3 112 
2 A buttercup   2   2  1 32 
3 A  rose   1   1  4 43 
4 B buttercup   1   1  3 13 
5 B  rose   1   2  2 25 

Этот пример довольно простой (мой набор данных ~ 5000 строк), и хотя здесь вы видите только две строки, которые необходимо суммировать, количество строк, которые нужно суммировать, варьируется и варьируется от 1 до ~ 45.

Я пробовал rowum() и tapply() с довольно мрачными результатами до сих пор (ошибки говорят мне, что эти функции не имеют смысла для факторов), поэтому, если бы вы могли даже указать мне в правильном направлении, я был бы очень признателен!

Большое спасибо!

+0

смотреть на 'plyr' и' data.table'. В основном это касается большинства вопросов. Удачи! – Chase

+0

См. Также http://4dpiecharts.com/2011/12/16/a-quick-primer-on-split-apply-combine-problems/ –

ответ

11

Надеюсь, следующий код довольно понятен. Он использует базовую функцию «агрегат», и в основном это говорит для каждой уникальной комбинации сайта, растения, обработки и plant_num посмотреть на сумму фруктов и сумму семян.

# Load your data 
data <- data.frame(site=c("A","A","A","A","B","B"), plant=c("buttercup","buttercup", 
"buttercup","rose","buttercup","rose"), treatment=c(1,1,2,1,1,1), 
plant_numb=c(1,1,2,1,1,2), fruits=c(1,2,1,4,3,2),seeds=c(45,67,32,43,13,25)) 

# Summarize your data 
aggregate(cbind(fruits, seeds) ~ 
     site + plant + treatment + plant_numb, 
     sum, 
     data = data) 
# site  plant treatment plant_numb fruits seeds 
#1 A buttercup   1   1  3 112 
#2 B buttercup   1   1  3 13 
#3 A  rose   1   1  4 43 
#4 B  rose   1   2  2 25 
#5 A buttercup   2   2  1 32 

Порядок изменения строк (и отсортированы по сайту, завод, ...), но мы надеемся, что это не слишком большая проблема.

Альтернативный способ сделать это - использовать ddply из пакета plyr.

library(plyr) 
ddply(data, .(site, plant, treatment, plant_numb), 
     summarize, 
     fruits = sum(fruits), 
     seeds = sum(seeds)) 
# site  plant treatment plant_numb fruits seeds 
#1 A buttercup   1   1  3 112 
#2 A buttercup   2   2  1 32 
#3 A  rose   1   1  4 43 
#4 B buttercup   1   1  3 13 
#5 B  rose   1   2  2 25 
+0

Awesome - Я просто играл с заполнителем после того, как задал вопрос, но вы «Я сильно ударил меня. Спасибо за вашу помощь. Однако еще один вопрос: когда я ввожу код, как вы показали, я получаю сообщение об ошибке «Ошибка в as.data.frame.default (x): не может принуждать класс« формулу »к data.frame" , Любые идеи о том, как заставить его работать? – user1371443

+0

Оба, к сожалению. Я получаю то же сообщение об ошибке как для примера, так и для моих фактических наборов данных (без пробелов):> aggregate (cbind (фрукты, семена) ~ сайт + завод + обработка + завод_нум, сумма, данные = данные) Ошибка в as .data.frame.default (x): не может принуждать класс «формулу» к data.frame – user1371443

+0

Решение plyr должно по-прежнему работать, я думаю. Но похоже, что у вас нет сводной версии формулы. Какую версию R вы используете? Я думаю, что совокупность позволила ввести формулу с 2.11. – Dason

4

И для полноты картины, вот data.table решения, как это было предложено @Chase. Для больших наборов данных это, вероятно, будет самым быстрым способом:

library(data.table) 
data.dt <- data.table(data) 
setkey(data.dt, site) 
data.dt[, lapply(.SD, sum), by = list(site, plant, treatment, plant_numb)] 

    site  plant treatment plant_numb fruits seeds 
[1,] A buttercup   1   1  3 112 
[2,] A buttercup   2   2  1 32 
[3,] A  rose   1   1  4 43 
[4,] B buttercup   1   1  3 13 
[5,] B  rose   1   2  2 25 

lapply(.SD, sum) часть суммирует все столбцы, которые не являются частью набора группировки (т. Е столбцы не в by функции)