【问题标题】:Use function like cumulative sum by group or by each list element in R使用 R 中按组或每个列表元素的累积总和之类的函数
【发布时间】:2014-06-11 10:38:52
【问题描述】:

我有以下数据:

col1 = c(rep("a",4),rep("b",8),rep("c",6), rep("d",2))
col2 = sample(-100:250, 20)
col3 = cumsum(col2)
data = data.table(col1, col2, col3)


和data.table:

    col1 col2 col3
 1:    a   56   56
 2:    a   90  146
 3:    a   85  231
 4:    a  214  445
 5:    b  -39  406
 6:    b  116  522
 7:    b   42  564
 8:    b  131  695
 9:    b  161  856
10:    b   54  910
11:    b   15  925
12:    b  229 1154
13:    c  166 1320
14:    c  224 1544
15:    c  -53 1491
16:    c   87 1578
17:    c -100 1478
18:    c  -11 1467
19:    d   28 1495
20:    d  143 1638

如您所见,它只是按 col1 分组。我想根据 col1 中的组进行一些计算(如 cumsum、count if 等)。

最后我想要:

col1 colsum countif>0  countif<0
a    445    4          0
b    709    7          1
c    313    3          3
d    171    2          0


@评论员 伙计们!请......我做了两个解决方案,第一个非常难看(放在这里没有意义,但基于创建一个列表并循环计算列表的每个元素)第二个是:

a1 = aggregate (col2 ~ col1, sum, date = date)
a2 = aggregate (col2> 0 ~ col1, sum, date = date)
a3 = aggregate (col2 <0 ~ col1, sum, date = date)
cbind (a1, a2 counfif_1 = [2], counfif_2 = a3 [2])

我只是在寻找漂亮又酷的东西。

【问题讨论】:

  • 好的,在阅读完包装小插曲之后,你到底卡在哪里了?
  • 您的问题相当于说“为我做这件事”。这不是这个网站的目的。
  • 伙计们!请...我做了两个解决方案,第一个非常难看,第二个是:a1 = aggregate (col2 ~ col1, sum, date = date) a2 = aggregate (col2> 0 ~ col1, sum, date = date) a3 = aggregate (col2

标签: r data.table cumsum


【解决方案1】:
data[, list(colsum = sum(col2),
            `countif>0` = sum(col2 > 0),
            `countif<0` = sum(col2 < 0)), by = col1]

##     col1 colsum countif>0 countif<0
## 1:    a    445         4          0
## 2:    b    709         7          1
## 3:    c    313         3          3
## 4:    d    171         2          0

【讨论】:

  • 你是对的!这是 data.table,这就是我改变接受的原因。
  • @MarekW 仅作记录,dplyr 也可以与 data.table 一起使用!
  • @DavidArenburg Nice data.table 解决方案,但我认为sum(col2 &gt;0) 可能会比length(col2[col2 &gt; 0]) 更快
  • @dickoa,您的解决方案返回了一个错误。你试过了吗?
  • @dickoa,好吧,你说服了我
【解决方案2】:

您可以使用dplyr 来实现类似的功能

library(dplyr)

set.seed(1)
col1 <- c(rep("a", 4), rep("b", 8), rep("c", 6), rep("d",2))
col2 <- sample(-100:250, 20)
data <- tbl_df(data.frame(col1, col2))
str(data)
## Classes ‘tbl_df’, ‘tbl’ and 'data.frame':    20 obs. of  3 variables:
##  $ col1: Factor w/ 4 levels "a","b","c","d": 1 1 1 1 2 2 2 2 2 2 ...
##  $ col2: int  -7 30 99 216 -31 210 225 127 115 -79 ...


data %>%
    group_by(col1) %>%
        summarise(colsum = sum(col2),
                  countifpos = sum(col2 > 0),
                  countifneg = sum(col2 < 0))
## Source: local data frame [4 x 4]

##   col1 colsum countifpos countifneg
## 1    a    338          3          1
## 2    b    497          4          4
## 3    c    758          6          0
## 4    d    184          2          0

【讨论】:

    【解决方案3】:

    您可以使用tapply 按组获取摘要 例如:

    这是您定义正在计算的指标的地方

    metrics =  function(x) { c(sum(x), length(x[x<0]) , length(x[x>0]) )}
    

    您使用metrics 函数通过tapply 函数按组计算指标

    tapply (data$col2, data$col1, metrics)
    $a
    [1] 241 -50 291
    
    $b
    [1] 526 -86 612
    
    $c
    [1] 483 -94 577
    
    $d
    [1] -88 -88   0
    

    然后您可以根据要求将此输出转换为数据框

    【讨论】:

    • 当然,但是 data.table 对于大型数据集更有效。
    • 我认为这甚至不会返回所需的结果。您可能应该将最后两个 sums 更改为 length 也许?
    猜你喜欢
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    相关资源
    最近更新 更多