【问题标题】:plyr ddply and summarise use in Rplyr ddply 并总结在 R 中的使用
【发布时间】:2012-08-18 18:07:18
【问题描述】:

您好,我想避免使用循环,因此想使用 plyr 中的一些东西来帮助解决我的问题。

我想创建一个函数,从数据框中获取每个因子的特定选择列的总和。

所以如果我们有以下示例数据...

df <- data.frame(cbind(x=rnorm(100),y=rnorm(100),z=rnorm(100),f=sample(1:10,100, replace=TRUE))) 
df$f <- as.factor(df$f)

即我想要类似的东西:

foo <- function(df.obj,colname){
     some code
}

其中df.obj 是上面的df 变量,而colname 参数可以是x、y 或z 中的任何一个。

并且我希望函数的输出/结果有一列独特因素(在上述情况下为 1:10)以及每个因素的 x 列中的值的总和。

我希望解决方案非常简单,并且可能会以某种方式使用ddply 或summarise,但无法弄清楚如何做到这一点,以便我可以将列名作为参数。

谢谢

【问题讨论】:

  • 这似乎非常适合data.table。

标签: r dataframe plyr data.table subset


【解决方案1】:

这似乎非常适合 data.table 以及 lapply(.SD,FUN) 和 .SDcols 参数

  • .SD 是一个 data.table,其中包含每个组的 x 数据子集,不包括组列。
  • .SDcols 是一个向量,其中包含您希望应用函数的列的名称 (FUN)

一个例子

设置data.table

library(data.table)
DT <- as.data.table(df)

x,y,z 列的总和 by f

DT[, lapply(.SD, sum), by = f, .SDcols = c("x", "y", "z")]

##      f       x       y       z
##  1:  4  4.8041  3.9788  1.2519
##  2:  2  1.1255 -0.8147  2.9053
##  3:  3  0.9699 -0.1550 -8.5876
##  4:  9  2.2685 -1.2734  1.0506
##  5:  5 -0.1282 -2.5512  5.0668
##  6: 10 -2.7397  0.5290 -0.3638
##  7:  1  2.9544 -3.1139 -1.3884
##  8:  8 -4.3488  0.6894  1.4195
##  9:  7  2.3152  0.6474  2.7183
## 10:  6 -0.1569  1.0142  0.9156

x 和 z 列的总和 by f

DT[, lapply(.SD, sum), by = f, .SDcols = c("x", "z")]

##      f       x       z
##  1:  4  4.8041  1.2519
##  2:  2  1.1255  2.9053
##  3:  3  0.9699 -8.5876
##  4:  9  2.2685  1.0506
##  5:  5 -0.1282  5.0668
##  6: 10 -2.7397 -0.3638
##  7:  1  2.9544 -1.3884
##  8:  8 -4.3488  1.4195
##  9:  7  2.3152  2.7183
## 10:  6 -0.1569  0.9156

计算平均值

的例子
DT[, lapply(.SD, mean), by = f, .SDcols = c("x", "y", "z")]

##      f        x        y        z
##  1:  4  0.36955  0.30606  0.09630
##  2:  2  0.10232 -0.07407  0.26412
##  3:  3  0.07461 -0.01193 -0.66059
##  4:  9  0.15123 -0.08489  0.07004
##  5:  5 -0.01425 -0.28346  0.56298
##  6: 10 -0.21075  0.04069 -0.02799
##  7:  1  0.29544 -0.31139 -0.13884
##  8:  8 -0.54360  0.08617  0.17744
##  9:  7  0.38586  0.10790  0.45305
## 10:  6 -0.07844  0.50710  0.45782

DT[, lapply(.SD, mean), by = f, .SDcols = c("x", "z")]

##      f        x        z
##  1:  4  0.36955  0.09630
##  2:  2  0.10232  0.26412
##  3:  3  0.07461 -0.66059
##  4:  9  0.15123  0.07004
##  5:  5 -0.01425  0.56298
##  6: 10 -0.21075 -0.02799
##  7:  1  0.29544 -0.13884
##  8:  8 -0.54360  0.17744
##  9:  7  0.38586  0.45305
## 10:  6 -0.07844  0.45782

【讨论】:

    【解决方案2】:

    这就是你所追求的吗?

    > ddply(df, .(f), colwise(sum))
        f          x           y          z
    1   1 -0.4190284  2.61101681  1.2280026
    2   2  1.1063977  2.40006922  4.9550079
    3   3  0.4498366 -4.00610558  0.9964754
    4   4  1.9325488 -2.81241212 -3.1185574
    5   5 -4.1077670 -1.01232884 -3.9852388
    6   6 -1.0488003 -2.42924689  3.5273636
    7   7  2.2999306  0.85930085 -0.6245167
    8   8 -4.8105311 -6.81352238 -2.1223436
    9   9 -2.8187083  5.03391770  1.6433896
    10 10  5.1323666 -0.06192382  1.8978994
    

    编辑:TS 提供的正确答案:

    foo <- function(df.obj,colname){ddply(df, .(f), colwise(sum))[,c("f",colname)]}
    

    【讨论】:

    • 不完全...虽然足够接近我可以从您写的内容中弄清楚...foo &lt;- function(df.obj,colname){ddply(df, .(f), colwise(sum))[,c("f",colname)]}我不知道 colwise 函数...谢谢...跨度>
    • 出于好奇,如果有第二个或第三个因子列并且我想根据该因子而不是 f 求和,我将如何去做...即我想将因子列名称作为参数添加到 foo 函数
    • 此:foo &lt;- function(df.obj, factorname, colname){ddply(df, factorname, colwise(sum,is.numeric))[,c(factorname,colname)]} 并致电:foo(df, "g", "y")
    【解决方案3】:

    我没有足够的代表发表评论,所以必须以答案形式提问 - 为什么要避免在 R 中使用循环?

    编辑:无论如何使用 plyr 我会使用 count()

    【讨论】:

    • 还有关于计数...如果您的意思是count(df,"f")(使用我的示例),这仅计算每个因素的出现次数
    • 即使您自己没有明确地创建一个循环,执行此操作的任何函数都肯定会使用循环吗?另外我想我一定是误解了,因为我认为你想要每个因素的出现次数
    • 如果不是出现次数,也许你想使用 count 的 wt_var 参数
    • 我认为*ply 函数实际上使用了循环,但是循环是用C 编写的,这使得它更快。但是,plyr 函数并不是最有效的。在大多数情况下,有更快的替代方案(例如data.table)。 plyr 包的主要优点是它的语法很好。
    • 循环通常不会比 plyr 或 base R 的 apply 函数等替代方法慢多少。在 R 中,循环往往被忽视的真正原因是循环中的代码是在其父环境中评估的,因此很容易无意中覆盖其他现有变量或创建破坏后续代码的变量。相比之下,plyr 和 apply 函数是在新环境中评估的,除非明确说明,否则不可能产生此类副作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 2016-01-09
    • 1970-01-01
    相关资源
    最近更新 更多