【问题标题】:Apply a function to groups within a data.frame in R将函数应用于 R 中的 data.frame 中的组
【发布时间】:2012-05-25 14:00:18
【问题描述】:

我正在尝试获取数据框中组(“a”和“b”)的变量 (v) 的累积总和。如何将底部的结果(其行的偶数正确编号)放入我的数据框的 cs 列?

> library(nlme)
> g <- factor(c("a","b","a","b","a","b","a","b","a","b","a","b"))
> v <- c(1,4,1,4,1,4,2,8,2,8,2,8)
> cs <- rep(0,12)
> d <- data.frame(g,v,cs)

> d
   g v cs
1  a 1 0
2  b 4 0
3  a 1 0
4  b 4 0
5  a 1 0
6  b 4 0
7  a 2 0
8  b 8 0
9  a 2 0
10 b 8 0
11 a 2 0
12 b 8 0

> r=gapply(d,FUN="cumsum",form=~g, which="v")
>r

$a     
   v   
1  1   
3  2   
5  3  
7  5  
9  7  
11 9  

$b    
    v 
2   4 
4   8 
6  12 
8  20 
10 28 
12 36 

> str(r)
List of 2
 $ a:'data.frame':  6 obs. of  1 variable:
  ..$ v: num [1:6] 1 2 3 5 7 9
 $ b:'data.frame':  6 obs. of  1 variable:
  ..$ v: num [1:6] 4 8 12 20 28 36

我想我可以想出一些费力的方法来将这些数据帧中的数据导入 d$cs,但是我缺少一些简单的调整。

【问题讨论】:

    标签: r dataframe apply


    【解决方案1】:

    split&lt;- 是一只非常奇怪的野兽

    split(d$cs, d$g) <- lapply(split(d$v, d$g), cumsum)
    

    导致

    > d
       g v cs
    1  a 1  1
    2  b 4  4
    3  a 1  2
    4  b 4  8
    5  a 1  3
    6  b 4 12
    7  a 2  5
    8  b 8 20
    9  a 2  7
    10 b 8 28
    11 a 2  9
    12 b 8 36
    

    【讨论】:

    • 那是split&lt;-.default。我没有意识到它的存在(或者它是 ave 的基础。)split&lt;-.data.frame 更奇怪。
    【解决方案2】:

    我会使用ave。如果您查看ave 的来源,您会发现它基本上包含了Martin Morgan 的solution。

    R> g <- factor(c("a","b","a","b","a","b","a","b","a","b","a","b"))
    R> v <- c(1,4,1,4,1,4,2,8,2,8,2,8)
    R> d <- data.frame(g,v)
    R> d$cs <- ave(v, g, FUN=cumsum)
    R> d
       g v cs
    1  a 1  1
    2  b 4  4
    3  a 1  2
    4  b 4  8
    5  a 1  3
    6  b 4 12
    7  a 2  5
    8  b 8 20
    9  a 2  7
    10 b 8 28
    11 a 2  9
    12 b 8 36
    

    【讨论】:

    • 我总是忘记ave;虽然结果和其他 2 个一样吗?
    • @TylerRinker:它与 Martin 的解决方案基本相同(请参阅我的编辑)。
    • 与 joran 相比,我很困惑 b/c。我忘记了 plyr 重新排列的东西。 +1
    • 不错,将 ave 添加到我的有用函数库中。
    • 谢谢!这是最简单的,所以我会用它。
    【解决方案3】:

    我为这些事情选择的工具是 plyr 包:

    require(plyr)
    > ddply(d,.(g),transform,cs = cumsum(v))
       g v cs
    1  a 1  1
    2  a 1  2
    3  a 1  3
    4  a 2  5
    5  a 2  7
    6  a 2  9
    7  b 4  4
    8  b 4  8
    9  b 4 12
    10 b 8 20
    11 b 8 28
    12 b 8 36
    

    【讨论】:

      【解决方案4】:
      > library(nlme)
      > g <- factor(c("a","b","a","b","a","b","a","b","a","b","a","b"))
      > v <- c(1,4,1,4,1,4,2,8,2,8,2,8)
      > cs <- rep(0,12)
      > d <- data.frame(g,v,cs)
      > d <- d[order(d$g),]
      > temp <- by(d$v,d$g,cumsum)
      > d$cs <- do.call("c",temp)
      > d
         g v cs
      1  a 1  1
      3  a 1  2
      5  a 1  3
      7  a 2  5
      9  a 2  7
      11 a 2  9
      2  b 4  4
      4  b 4  8
      6  b 4 12
      8  b 8 20
      10 b 8 28
      12 b 8 36
      

      使用 by 函数的另一种解决方案,但我必须先订购数据

      【讨论】:

        猜你喜欢
        • 2017-09-02
        • 2014-09-05
        • 2011-12-28
        • 1970-01-01
        • 2018-07-17
        • 2021-06-30
        • 2017-01-16
        • 2015-01-18
        • 1970-01-01
        相关资源
        最近更新 更多