我有以下这种结构的数据表:
+-------------------+
| id | key | value |
+-----+-----+-------+
| 1 | A | 1000 |
| 1 | A | 2000 |
| 1 | B | 2001 |
| 1 | A | 2002 |
| 1 | A | 2004 |
| 2 | B | 2002 |
| 2 | C | 2002 |
+-------------------+
我的目标是通过id和key对值进行求和,而不是仅仅通过id和key进行分组,我只想在连续行的id和key对相同的情况下对值进行求和。
结果应为:
+-------------------+
| id | key | value |
+-----+-----+-------+
| 1 | A | 3000 |
| 1 | B | 2001 |
| 1 | A | 4006 |
| 2 | B | 2002 |
| 2 | C | 2002 |
+-------------------+
有没有达到这个结果?
答案 0 :(得分:8)
我们可以使用rleid
版本devel
中的data.table
,即v1.9.5 +。安装devel版本的说明是here
。
我们将'data.frame'转换为'data.table'。从“key”列创建另一个分组列“ind”。通过'id'和'ind'分组,我们得到'{1}}的'value'并得到'key'的第一个元素。我们可以将'ind'分配给NULL,因为在预期的输出中不需要它。
sum
或者@Frank建议,我们可以在library(data.table)
setDT(df1)[,list(value = sum(value), key=key[1L]),
by = .(ind=rleid(key), id)][, ind:=NULL][]
# id value key
#1: 1 3000 A
#2: 1 2001 B
#3: 1 4006 A
#4: 2 2002 B
#5: 2 2002 C
中使用mutliple列,将其用作分组变量,获取其他变量的第一个元素和{value'的rleid
,将不需要的列分配给sum
或使用NULL
的标准data.table
子集。
with = FALSE
或者我们可以使用setDT(df1)[, list(id=id[1L], key=key[1L], value=sum(value)) ,
by = .(r=rleid(id, key))][, r:= NULL][]
# id key value
#1: 1 A 3000
#2: 1 B 2001
#3: 1 A 4006
#4: 2 B 2002
#5: 2 C 2002
。我们通过比较'key'的相邻元素来创建分组变量'ind',并使用dplyr
获取'value'的sum
和'key'的first
元素。
summarise
注意:在library(dplyr)
df1 %>%
group_by(ind= cumsum(key!=lag(key, default=TRUE)), id) %>%
summarise(value=sum(value), key=first(key)) %>%
ungroup() %>%
select(-ind)
# id value key
#1 1 3000 A
#2 1 2001 B
#3 1 4006 A
#4 2 2002 B
#5 2 2002 C
和dplyr
中,我们也可以将“关键字”列作为分组变量,然后移除data.table
或key=key[1L]
。
或者我们key=first(key))
数据集通过创建“ind”列并使用transform
中的aggregate
来获得预期的输出
base R
df1 <- transform(df1, ind = cumsum(c(TRUE,head(key,-1)!=tail(key,-1))))
aggregate(value~., df1, FUN=sum)[-3]
# id key value
#1 1 A 3000
#2 1 B 2001
#3 1 A 4006
#4 2 B 2002
#5 2 C 2002