【问题标题】:Loops to create new variables in ddply在 ddply 中创建新变量的循环
【发布时间】:2011-08-17 22:50:10
【问题描述】:

我正在使用 ddply 来聚合和汇总数据框变量,并且我有兴趣遍历我的数据框列表以创建新变量。

new.data <- ddply(old.data, 
                  c("factor", "factor2"),
                  function(df)
                    c(a11_a10 = CustomFunction(df$a11_a10),
                      a12_a11 = CustomFunction(df$a12_a11),
                      a13_a12 = CustomFunction(df$a13_a12),
                      ...
                      ...
                      ...))

有没有办法让我在 ddply 中插入一个循环,这样我就可以避免写出每个新的汇总变量,例如

for (i in 11:n) {
  paste("a", i, "_a", i - 1) = CustomFunction(..... )
}

我知道这不是它的实际实现方式,但我只是想展示我将如何概念化它。有没有办法在我在 ddply 中调用的函数中或通过列表来执行此操作?

更新:因为我是新用户,所以我无法发布自己的问题的答案:

我的回答涉及 Nick 的回答和 Ista 的评论中的想法:

func <- function(old.data, min, max, gap) {
  varrange <- min:max
  usenames <- paste("a", varrange, "_a", varrange - gap, sep="")
  new.data <- ddply(old.data,
                    .(factor, factor2),
                    colwise(CustomFunction, c(usenames)))
}

【问题讨论】:

  • 您可能在关注transform()summarize()summarize 的帮助页面展示了一些很好的例子。
  • @Chase - Re: 总结,我可以用(old.data, summarise(old.data[, paste("a", i, "_a") 为 (i in 11:n) 做, i - 1, sep="")], llist(factor, factor2), CustomFunction))
  • 如果您使您的示例可重现,那么您的潜在帮助者会更轻松。在没有工作示例的情况下,我只能猜测您正在寻找 ?colwise(请参阅与 ddply 一起使用的示例)。
  • @Ista - 谢谢,在得知尼克最初将变量名加载到内存中之后,colwise 正是我想要的。
  • +1 @Casey。非常优雅。

标签: r for-loop plyr


【解决方案1】:

基于@Nick 的出色回答,这是解决问题的一种方法

foo <- function(df){
  names   = paste("a", 11:n, "_a", 10:(n-1), sep = "")
  results = sapply(df[,names], CustomFunction)
}

new.data = ldply(dlply(old.data, c("factor", "factor2")), foo)

这是使用ggplot2 中的tips 数据集的示例应用程序。假设我们想通过组合sexsmoker 来计算tiptotal_bill 的平均值,下面是代码的工作原理

foo = function(df){names = c("tip", "total_bill"); sapply(df[,names], mean)}
new = ldply(dlply(tips, c("sex", "smoker")), foo)

它产生如下所示的输出

         .id      tip total_bill
1  Female.No 2.773519   18.10519
2 Female.Yes 2.931515   17.97788
3    Male.No 3.113402   19.79124
4   Male.Yes 3.051167   22.28450

这是你要找的吗?

【讨论】:

  • @ Ramnath- 这正是我正在寻找的,除了我希望因子/ID 变量保持分离。我相信我在更新中给出的答案将使我能够做到这一点,但是您巧妙地回答了我的问题并将示例变成了我将尝试适应的功能。谢谢。
  • @Casey。你的回答更优雅!!我赞成它,如果可以的话,我会给它+2。干得好
  • 所有这些都可以使用colwise在一行中完成。看我的回答。
【解决方案2】:

如果我对您的理解正确,您实际上是想对ddply data.frame 中的每一列应用自定义函数。

好消息是有一个 ddply 函数可以做到这一点。这意味着您的问题的解决方案归结为一条线:

以@Ramnath 的优秀示例为基础:

library(ggplot2)
customfunction <- mean
ddply(tips, .(sex, smoker), numcolwise(customfunction))

     sex smoker total_bill      tip     size
1 Female     No   18.10519 2.773519 2.592593
2 Female    Yes   17.97788 2.931515 2.242424
3   Male     No   19.79124 3.113402 2.711340
4   Male    Yes   22.28450 3.051167 2.500000

之所以如此,是因为colwise 将处理向量的函数转换为处理 data.frame 中列的函数。 colwise 有两种变体:numcolwise 仅适用于数字列,catcolwise 适用于分类列。更多信息请见?colwise

编辑:

感谢您可能不希望将该函数应用于 data.frame 中的所有列。尽管如此,我发现这种语法非常简单,我的一般方法是修改我传递给ddply 的data.frame。例如,以下修改示例子集tips 以排除某些列。解决方案仍然是单行:

ddply(tips[, -2], .(sex, smoker), numcolwise(customfunction))

     sex smoker total_bill     size
1 Female     No   18.10519 2.592593
2 Female    Yes   17.97788 2.242424
3   Male     No   19.79124 2.711340
4   Male    Yes   22.28450 2.500000

【讨论】:

  • 这仅在您将该函数应用于除用于拆分的列之外的所有列时才有效。如果 OP 确实是这种情况,那么这将是最好的解决方案。否则,我认为OP提出的解决方案更通用。
  • @Ramnath,同意,好点。尽管如此,在我的工作流程中,我更愿意做一个简单的 data.frame 子集,而不是一些复杂的编码。我已经编辑了我的答案以反映这一点。
  • colwise 有一个 cols 参数,它接受变量名的字符向量...
【解决方案3】:

分步:

varrange<-11:n
usenames<-paste("a", varrange, "_a", varrange - 1, sep="")
results<-sapply(usenames, function(curname){CustomFunction(df[,curname])})
names(results)<-usenames

这是你想要的吗?

【讨论】:

  • 感谢您的回复,但这不是我想要的。我确实希望最终得到一个数据框,其中包括每个“因子”和“因子2”组合的唯一观察结果,以及我的 CustomFunction 为我的两个因子的每个唯一组合的每个“a”变量的输出。
  • 基本上我正在寻找 ddply 功能,但使用循环或列表方法自动创建变量。
猜你喜欢
  • 2020-01-16
  • 1970-01-01
  • 2020-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多