在R和ddply中,是否可以避免在使用ddply时枚举我需要的所有列?

时间:2012-02-24 16:05:22

标签: r plyr

其他帖子表明ddply是一个很好的主力。 我正在尝试学习xxply函数,但我无法解决这个问题。

这是我的

library(ggplot2)
(df= tips[1:5,])
             total_bill                   tip    sex smoker day   time size
1 16.989999999999998437 1.0100000000000000089 Female     No Sun Dinner    2
2 10.339999999999999858 1.6599999999999999201   Male     No Sun Dinner    3
3 21.010000000000001563 3.5000000000000000000   Male     No Sun Dinner    3
4 23.679999999999999716 3.3100000000000000533   Male     No Sun Dinner    2
5 24.589999999999999858 3.6099999999999998757 Female     No Sun Dinner    4

我需要这样的事情

ddply(df
       ,.(<do I have to enumerate all columns I need to operate on here?)>
       , function(x) {if size>=3 return(size) else return(total_bill+tip)
     )

(这个例子是一个假的问题(没有现实意义)并且只用更大的数据来证明我的问题)

  1. 我无法让ddply代码正确阅读帮助文件。任何建议表示赞赏。甚至是很棒的ddply教程?

  2. 我喜欢ddply,我只能将我的数据帧作为输入传递,但在第二个参数中,我不得不枚举以后需要的所有列。有没有办法传递整行(所有列)?

  3. 我喜欢动态定义函数,但我不知道如何在R(我的最后一个参数)中使我的伪代码正确。

3 个答案:

答案 0 :(得分:4)

根据您的代码,看起来您根本不需要在这里使用plyr。在我看来,你正在为data.frame的每一行计算一个新变量。如果是这种情况,那么只需使用一些基本的R函数:

dat <- transform(dat, newval = ifelse(size >= 3, size, total_bill + tip))

  total_bill  tip    sex smoker day   time size newval
1      16.99 1.01 Female     No Sun Dinner    2  18.00
2      10.34 1.66   Male     No Sun Dinner    3   3.00
3      21.01 3.50   Male     No Sun Dinner    3   3.00
4      23.68 3.31   Male     No Sun Dinner    2  26.99
5      24.59 3.61 Female     No Sun Dinner    4   4.00

很抱歉,如果我误解了你在做什么。如果你确实需要将data.frame的整行传递给没有分组变量的plyr,也许你可以将它视为margin = 1的数组?即adply(dat, 1, ...)

plyr的精彩介绍:www.jstatsoft.org/v40/i01/paper

答案 1 :(得分:3)

第二个参数是“拆分”变量。所以在你的样本数据集中,如果你想看到两性之间消费习惯的差异,你会提供.(sex),或者如果你想要所有可能的分类变量,是的,你将不得不提供它们{ {1}}。

另外,在使用.(sex, smoker, day, time)时,您的功能应该是ddply并返回data.frame。目前它返回一个向量。此外,data.frame未进行矢量化,您应使用if

ifelse

如果你没有指定返回值,ddply(df, .(sex), function(x) { x$new.var <- ifelse(x$size >= 3, x$size, x$total_bill + x$tip) return(x) }) 将返回计算出的最后一个向量。

我唯一的另一个建议就是继续玩R。最终它会点击,你会爱上它!

答案 2 :(得分:0)

不知道这是否仍然有用。虽然我不确定这是否足够,但我习惯于解决以下与您类似的任务:

void OnCollisionEnter2D(Collision2D collision)
{
    bg = GameObject.Find(bg_name);
    if (collision.gameObject.tag == "floor")
    {
        print("floor collision");
        bg.GetComponent<ControlGame>().ShootBall();
    }
}