您可以使用merge
and aggregate
(即使没有任何东西可以聚合):
merge(mydf,
cbind(aggregate(Value ~ Species, mydf, sum,
subset = c(Status != "Native")),
Status = "IC.Total"),
all = TRUE)
# Species Status Value
# 1 A Introduced 10
# 2 A Native 3
# 3 A IC.Total 10
# 4 B Crypt 6
# 5 B IC.Total 6
# 6 C Introduced 19
# 7 C Native 4
# 8 C IC.Total 19
我使用aggregate
它是因为它有一个方便的参数,可以让您对数据进行子集化。在这种情况下,我们对“Native”不感兴趣。此外,我们知道对于一个物种,我们永远不会同时拥有“Introduced”和“Crypt”,并且我们知道“Introduced”或“Crypt”永远不会有多个值,因此将sum
其用作我们的聚合函数不会不要改变任何东西。
更新
即使您有多个“值”变量(正如您在评论中指出的那样),此解决方案背后的这一概念仍然有效,但需要进行一些细微的修改,如下所示。
首先,让我们整理一些数据:
mydf <- data.frame(
Species = c("A", "A", "B", "C", "C"),
Status = c("Introduced", "Native", "Crypt", "Introduced", "Native"),
Value1 = c(10, 3, 6, 19, 4),
Value2 = c(6, 8, 12, 19, 5),
Value3 = c(18, 19, 14, 13, 2))
mydf
# Species Status Value1 Value2 Value3
# 1 A Introduced 10 6 18
# 2 A Native 3 8 19
# 3 B Crypt 6 12 14
# 4 C Introduced 19 19 13
# 5 C Native 4 5 2
其次,和以前一样使用aggregate
and merge
,但要注意细微的差别。首先,我们不能使用subset
之前的方式,所以不是聚合整个数据集,而是只聚合我们感兴趣的行。其次,我们添加了“状态”作为分组变量,它应该与您所描述的当前数据结构相比,您的结果不会产生任何影响。第三,在我们聚合之后,我们需要删除“状态”列并添加一个新的状态列(这就是[-2]
代码正在做的 - 删除第二列。)
在这里,所有内容都在一个整洁的包装中:
merge(mydf,
cbind(aggregate(. ~ Species + Status,
mydf[mydf$Status != "Native", ], sum)[-2],
Status = "IC.Total"),
all = TRUE)
# Species Status Value1 Value2 Value3
# 1 A Introduced 10 6 18
# 2 A Native 3 8 19
# 3 A IC.Total 10 6 18
# 4 B Crypt 6 12 14
# 5 B IC.Total 6 12 14
# 6 C Introduced 19 19 13
# 7 C Native 4 5 2
# 8 C IC.Total 19 19 13