【问题标题】:Cumulative sum conditional over multiple columns in r dataframe containing the same values在包含相同值的 r 数据框中的多个列上的累积和条件
【发布时间】:2015-11-13 01:38:15
【问题描述】:

假设我的 data.frame 如下所述:

df<-as.data.frame(cbind("Home"=c("a","c","e","b","e","b"),
"Away"=c("b","d","f","c","a","f"))
df$Index<-rep(1,nrow(df))

   Home Away Index
1    a    b     1
2    c    d     1
3    e    f     1
4    b    c     1
5    e    a     1
6    b    f     1

我想要做的是使用索引列计算每个字符 a - f 的累积总和,无论它们是否在 HomeAway 列中。因此,一个名为Cumulative_Sum_Home 的列,例如,获取Home 行中的字符,在第6 行的情况下使用“b”,并计算“b”在HomeAway 中出现的次数包括第 6 行在内的所有先前行中的列。因此,在这种情况下,b 在前 6 行中累计出现了 3 次,因此Cumulative_Sum_Home 给出的值为 3。同样的逻辑适用于Cumulative_Sum_Away 列。以第 5 行为例,字符“a”出现在 Away 列中,并且在该行之前在 Home 或 Away 列中累计出现了 2 次,因此列 Cumulative_Sum_Away takes 的值为 2。

 Home Away Index   Cumulative_Sum_Home  Cumulative_Sum_Away
1    a    b     1        1                    1
2    c    d     1        1                    1
3    e    f     1        1                    1
4    b    c     1        2                    2 
5    e    a     1        2                    2 
6    b    f     1        3                    2 

我不得不承认我完全不知道如何解决这个问题。我试过查看data.table 方法,但我以前从未使用过该软件包,所以我无法立即看到如何解决它。任何提示都会受到极大的欢迎。

【问题讨论】:

  • 在我做太多事情之前,您是否能够确认您的真实数据框中的值将成为因素?您不能cumsum 因素,因为它们是序数。
  • 嗨 - 是的,我的真实数据框中的“Home”和“Away”列中的值是因素。我添加了(数字)“索引”列作为使用 cumsum 函数解决问题的一种可能方式。

标签: r


【解决方案1】:

有可以让这个更精简的空间,但如果这对你来说并不重要,那么这应该没问题。

NewColumns = list()

for ( i in sort(unique(c(levels(df[,"Home"]),levels(df[,"Away"]))))) {

   NewColumnAddition = i == df$Home | i ==df$Away
   NewColumnAddition[NewColumnAddition] = cumsum(NewColumnAddition[NewColumnAddition])
   NewColumns[[i]] = NewColumnAddition

}


df$Cumulative_Sum_Home = sapply(
   seq(nrow(df)),
   function(i) {
      NewColumns[[as.character(df[i,"Home"])]][i]
   }
)


df$Cumulative_Sum_Away = sapply(
   seq(nrow(df)),
   function(i) {
      NewColumns[[as.character(df[i,"Away"])]][i]
   }
)



> df
  Home Away Index HomeSum AwaySum
1    a    b     1       1       1
2    c    d     1       1       1
3    e    f     1       1       1
4    b    c     1       2       2
5    e    a     1       2       2
6    b    f     1       3       2

这是data.table 替代方案 -

setDT(df)
for ( i in sort(unique(c(levels(df[,Home]),levels(df[,Away]))))) {

   df[, TotalSum := cumsum(i == Home | i == Away)]
   df[Home == i, Cumulative_Sum_Home := TotalSum]
   df[Away == i, Cumulative_Sum_Away := TotalSum]

}
df[,TotalSum := NULL]

【讨论】:

  • 非常感谢 Codoremifa。我不需要精益的解决方法 - 我可以很高兴地确认您提出的两种方法都完全符合要求。
猜你喜欢
  • 1970-01-01
  • 2021-03-30
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 2022-12-05
  • 1970-01-01
相关资源
最近更新 更多