2016-10-03 3 views
0

Так что недавно я изучил функции агрегата, и я нахожу его полезным для больших наборов данных, с которыми я работаю. Обычно я вручную манипулирую данными в excel, который, хотя и эффективен, занимает очень много времени.Использовать агрегат для облегчения расчетов

Так что мне было интересно, можно ли сделать следующее. У меня есть набор данных, который аналогичен структурированный как так (но гораздо больше):

Fruit Crate Mass 
Apple A  4 
Banana A  3.4 
Orange B  2 
Apple C  2.1 
Apple C  4.5 
Banana C  5 
Orange D  1 
Apple D  1.3 
Orange D  2.4 
Orange D  3.2 
Orange E  2 
Banana E  1.1 
Banana E  0.7 
Apple E  2 

Теперь я знаю, что с этим я получаю мессу за обрешетку:

TotalCrate<-aggregate(data$Mass,list(crate=data$Crate), sum)

И с этим я месса на фрукты в ящике:

FruitperCrate<-aggregate(data$Mass, list(fruit=data$Fruit, crate=data$Crate), sum)

Теперь есть способ, что я могу получить процент массы плодов на обрешетке, поэтому в основном, я Есть ли способ разделить массу плода на общую массу для каждого соответствующего ящика? И если да, то как я могу это сделать для справок в будущем.

Любая помощь приветствуется.

Спасибо

+0

насчет 'FruitperCrate $ PercentMassOfFruitPerCrate <- FruitperCrate $ х/TotalCrate [FruitperCrate $ клеть, "х"]'? – HubertL

+1

Пожалуйста, укажите входные данные в воспроизводимой форме. См. [Mcve]. В этом случае я сделал это для вас в Заметке в конце моего ответа. –

ответ

3

1) Первый агрегат по Fruit и Crate, а затем использовать ave с prop.table, чтобы получить пропорции каждого плода в обрешетке:

ag <- aggregate(Mass ~ Fruit + Crate, data, sum) 
tr <- transform(ag, percent = 100 * ave(Mass, Crate, FUN = prop.table)) 

даяние:

> tr 
    Fruit Crate Mass percent 
1 Apple  A 4.0 54.05405 
2 Banana  A 3.4 45.94595 
3 Orange  B 2.0 100.00000 
4 Apple  C 6.6 56.89655 
5 Banana  C 5.0 43.10345 
6 Apple  D 1.3 16.45570 
7 Orange  D 6.6 83.54430 
8 Apple  E 2.0 34.48276 
9 Banana  E 1.8 31.03448 
10 Orange  E 2.0 34.48276 

или графически:

library(ggplot2) 
ggplot(tr, aes(Crate, percent, fill = Fruit)) + 
    geom_bar(stat = "identity") + 
    scale_fill_manual(values = c("red", "yellow", "orange")) 

screenshot

1a) Это также может быть выражено в magrittr трубопровода, как это:

library(magrittr) 
data %>% 
    do(aggregate(Mass ~ Fruit + Crate, ., sum)) %>% 
    transform(percent = 100 * ave(Mass, Crate, FUN = prop.table)) 

2) и вот альтернатива, используя dplyr, который следует подобной логике:

library(dplyr) 
data %>% 
    group_by(Crate, Fruit) %>% 
    summarize(Mass = sum(Mass)) %>% 
    ungroup() %>% 
    group_by(Crate) %>% 
    mutate(percent = 100 * prop.table(Mass)) %>% 
    ungroup() 

, дающий:

# A tibble: 10 x 4 
    Crate Fruit Mass percent 
    <fctr> <fctr> <dbl>  <dbl> 
1  A Apple 4.0 54.05405 
2  A Banana 3.4 45.94595 
3  B Orange 2.0 100.00000 
4  C Apple 6.6 56.89655 
5  C Banana 5.0 43.10345 
6  D Apple 1.3 16.45570 
7  D Orange 6.6 83.54430 
8  E Apple 2.0 34.48276 
9  E Banana 1.8 31.03448 
10  E Orange 2.0 34.48276 

3) А 2d макет можно было получить с помощью xtabs:

xt <- 100 * prop.table(xtabs(Mass ~ Crate + Fruit, data), 1) 

подача:

> xt 
    Fruit 
Crate  Apple Banana Orange 
    A 54.05405 45.94595 0.00000 
    B 0.00000 0.00000 100.00000 
    C 56.89655 43.10345 0.00000 
    D 16.45570 0.00000 83.54430 
    E 34.48276 31.03448 34.48276 

, которые могут быть легко представлены в виде графика, как это:

plot(xt, col = c("red", "yellow", "orange"), 
    main = "Proportion of Mass of Fruit per Crates") 

Давая:

screenshot

2D-макет может быть преобразован в длинной форме с ftable:

ftable(xt, row.vars = 1:2) 

давая:

Crate Fruit    
A  Apple 54.05405 
     Banana 45.94595 
     Orange 0.00000 
B  Apple  0.00000 
     Banana 0.00000 
     Orange 100.00000 
C  Apple 56.89655 
     Banana 43.10345 
     Orange 0.00000 
D  Apple 16.45570 
     Banana 0.00000 
     Orange 83.54430 
E  Apple 34.48276 
     Banana 31.03448 
     Orange 34.48276 

Примечание 1: Эти две строки кода в вопросе может быть записана с использованием формулы:

aggregate(Mass ~ Crate, data, sum) 

aggregate(Mass ~ Fruit + Crate, data, sum) 

Примечание 2: вход используется в воспроизводимой форме:

Lines <- "Fruit Crate Mass 
Apple A  4 
Banana A  3.4 
Orange B  2 
Apple C  2.1 
Apple C  4.5 
Banana C  5 
Orange D  1 
Apple D  1.3 
Orange D  2.4 
Orange D  3.2 
Orange E  2 
Banana E  1.1 
Banana E  0.7 
Apple E  2" 
data <- read.table(text = Lines, header = TRUE) 
0

Вот решение для Вас, используя data.table, хотя есть, конечно, и другие способы:

library(data.table) 
setDT(data) 
data[ , mass := sum(mass), by = .(crate, fruit) ] 
data <- unique(data) 
data[ , total.mass.crate := sum(mass), by = crate ] 
data[ , percentage.mass.crate := (mass/total.mass.crate) * 100 ] 

Таким образом, мы первые агрегирование массы для каждого плода внутри каждого ящика (так как я обратите внимание, что некоторые фрукты перечислены более одного раза в одном ящике), чтобы получить общую массу для этих фруктов в ящике. Затем мы добавляем столбец, чтобы показать общую массу каждого ящика, показывая значение в каждой строке. Затем, разделив массу каждого плода на общую массу для этого ящика, получим процент массы для каждого плода в ящике.

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