【问题标题】:Conditional sum based on indicator基于指标的条件总和
【发布时间】:2013-03-09 21:21:28
【问题描述】:

我有一个这样的数据框:

   A   B   Ind
1 10   8     1
2  9  10     2
3  7   1     2
4 19  20     1
5  .   .     .

如何根据Ind 值对列求和?如果Ind==1,则从列A 求和,如果Ind==2,则从列B 求和。例如,前 4 行的输出应该是 10+10+1+19=30,其中前 10 行在 A,第二个 10 在B,第三个 1 在B,第四个 19 在A

【问题讨论】:

  • 我知道这可以通过 for 循环 + if 语句来完成。有没有办法快速做到这一点?

标签: r sum data-manipulation


【解决方案1】:

另一个使用I的选项

 sum(with(dat,A*I(Ind==1)+B*(Ind==2)))

【讨论】:

  • I 的有趣用法。我不会想到这里。 +1
【解决方案2】:

假设你的data.frame被称为“mydf”,你可以使用ifelse如下:

sum(with(mydf, ifelse(Ind == 1, A, B)))

这是ifelse 部分的结果:

> with(mydf, ifelse(Ind == 1, A, B))
[1] 10 10  1 19

当然,如果你有多个条件,你可以根据需要嵌套它们。


这是一个使用基本子集的更详细的替代方案:

sum(with(mydf, c(mydf[Ind == 1, "A"], mydf[Ind == 2, "B"])))

【讨论】:

  • 最后一行没有准确返回。如果您通过此行生成数据:mydf <- data.frame("A"=c(1,22,1,2,106,0),"B"=c(0,0,4,0,44,4),"Ind"=c(1,1,2,1,1,2)),而with(mydf,c(mydf[Ind==1,"A"],mydf[Ind==2,"B"])) 不会给您 1,22,4,2,106,4。相反,它会给你 1,22,2,106,4,4。
  • @Boxuan,您在任何地方都没有提到值出现的 order 很重要,而且据我在数学课上的回忆,它并不重要补充。
  • 你绝对是对的。顺序并不重要。我只是好奇为什么with 函数不按顺序返回行。
  • @Boxuan,你应该关注的不是with 函数。所有三个建议都使用with 纯粹是为了方便不必重复输入data.frame 名称。我展示的第二个选项基本上将两个子集附加在一起,这就是不保留顺序的原因。 agstudy 的解决方案将两个向量相加,其中每个向量中的几个值为零,ifelse 逐行向下继续data.frame。因此,ifelseI 解决方案将保留行顺序,但子集版本不会。
【解决方案3】:

使用which的解决方案:

sum( df$A[which(df$Ind==1)] , df$B[which(df$Ind==2)] )

【讨论】:

    猜你喜欢
    • 2021-11-05
    • 1970-01-01
    • 2016-05-31
    • 2022-01-07
    • 1970-01-01
    • 2022-10-24
    • 2021-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多