我希望按名称聚合数据框的两列,具体如下:
parts
和fruits
parts
列
parts
值并不重要,所有内容都已汇总,但Grape和Kiwi的parts
值应该成为新的fruits
名称< / LI>
第一眼看上去听起来很简单,但经过数小时的反复试验后,我找不到任何有用的解决方案。这是一个例子:
theDF <- data.frame(dates = as.Date(c(today()+20)),
fruits = c("Apple","Apple","Apple","Apple","Banana","Banana","Banana","Banana",
"Strawberry","Strawberry","Strawberry","Strawberry","Grape", "Grape",
"Grape","Grape", "Kiwi","Kiwi","Kiwi","Kiwi"),
parts = c("Big Green Apple","Apple2","Blue Apple","XYZ Apple4",
"Yellow Banana1","Small Banana","Banana3","Banana4",
"Red Small Strawberry","Red StrawberryY","Big Strawberry",
"StrawberryZ","Green Grape", "Blue Grape", "Blue Grape",
"Blue Grape","Big Kiwi","Small Kiwi","Big Kiwi","Middle Kiwi"),
stock = as.vector(sample(1:20)) )
当前数据框:
所需的输出:
答案 0 :(得分:5)
我们可以使用data.table
。如果有一些模式,比如结尾字符是大写字母或数字中的数字&#39;要删除的列,我们可以使用sub
来执行该操作,并将其用作分组变量以及“日期”。并获得&#39; stock&#39;的sum
。
library(data.table)
setDT(theDF)[,.(stock = sum(stock)) , .(dates, fruits = sub("([0-9]|[A-Z])$", "", parts))]
# dates fruits stock
#1: 2016-06-19 Apple 46
#2: 2016-06-19 Banana 35
#3: 2016-06-19 Strawberry 38
#4: 2016-06-19 Green Grape 12
#5: 2016-06-19 Blue Grape 21
#6: 2016-06-19 Big Kiwi 37
#7: 2016-06-19 Small Kiwi 14
#8: 2016-06-19 Middle Kiwi 7
或者使用dplyr
,我们可以类似地实施相同的方法。
library(dplyr)
theDF %>%
group_by(dates, fruits = sub('([0-9]|[A-Z])$', '', parts)) %>%
summarise(stock = sum(stock))
如果没有模式且仅基于手动识别“水果”中的元素,则创建vector
元素,使用%chin%
获取&#中的逻辑索引39;我&#39;,分配(:=
)&#39;部分&#39;对应于&#39; i&#39;到了水果&#39;然后通过&#39; date&#39;,&#39; fruit&#39;来做小组。并获得&#39; stock&#39;的sum
。
setDT(theDF)[as.character(fruits) %chin% c("Grape", "Kiwi"),
fruits := parts][, .(stock = sum(stock)), .(dates, fruits)]
theDF <- structure(list(dates = structure(c(16971, 16971, 16971, 16971,
16971, 16971, 16971, 16971, 16971, 16971, 16971, 16971, 16971,
16971, 16971, 16971, 16971, 16971, 16971, 16971), class = "Date"),
fruits = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 5L,
5L, 5L, 5L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L), .Label = c("Apple",
"Banana", "Grape", "Kiwi", "Strawberry"), class = "factor"),
parts = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 14L,
15L, 16L, 16L, 11L, 10L, 10L, 10L, 9L, 13L, 9L, 12L), .Label = c("Apple1",
"Apple2", "Apple3", "Apple4", "Banana1", "Banana2", "Banana3",
"Banana4", "Big Kiwi", "Blue Grape", "Green Grape", "Middle Kiwi",
"Small Kiwi", "StrawberryX", "StrawberryY", "StrawberryZ"
), class = "factor"), stock = c(8, 19, 15, 4, 6, 18, 1, 10,
9, 16, 11, 2, 12, 13, 5, 3, 17, 14, 20, 7)), .Names = c("dates",
"fruits", "parts", "stock"), row.names = c(NA, -20L), class = "data.frame")
答案 1 :(得分:4)
另一种方法是在第一步中创建适当的分组变量,然后使用您希望按组汇总的任何方法。在这里,我使用dplyr
,您可以使用其他人(data.table
等)。
library(dplyr)
theDF <- data.frame(fruits, parts, stock, stringsAsFactors = F)
theDF$fruits <- with(theDF, ifelse(fruits=="Kiwi" | fruits=="Grape", parts, fruits))
theDF %>% group_by(fruits) %>% summarise(stock = sum(stock))
Source: local data frame [8 x 2]
fruits stock
(chr) (int)
1 Apple 34
2 Banana 35
3 Big Kiwi 26
4 Blue Grape 32
5 Green Grape 7
6 Middle Kiwi 12
7 Small Kiwi 19
8 Strawberry 45
我没有找到函数today()
,所以我跳过了日期列。您可以将date
插入到分组中,然后将其添加回group_by(fruits, date)
,以便将其保留在所需的输出中。