在 R 中使用带有多个参数的匿名函数
Posted
技术标签:
【中文标题】在 R 中使用带有多个参数的匿名函数【英文标题】:using anonymous functions in R with multiple arguments 【发布时间】:2012-10-15 17:27:41 【问题描述】:我正在尝试在数据框中生成新变量,这些变量以数据框中的两个(或更多)其他变量为条件。我相信 R 中的循环函数(即 lapply、sapply 等)对于此目的是有用且有效的。然而,我的方法有些不对劲,我不知道是什么。
M <- data.frame(x=c("A", "A", "B", "B"), y=c(1,2,1,2))
使用此数据框,我想生成一个新列 z,其中包含当 x == "A"
和 y == 1
时为 TRUE 的逻辑。以下代码是我能想到的最好的,但似乎只评估我的第一个条件。
M$z <- sapply(M$x, function(x,y) if((x == "A") && (y == 1)) T else F, M$y)
可以根据我的目的修复此代码吗?
在 R 中是否有更好的方法来执行此操作,也许使用其他循环函数?
【问题讨论】:
【参考方案1】:这是transform
函数的任务
transform(M, z=ifelse((x == "A") & (y == 1), T, F))
x y z
1 A 1 TRUE
2 A 2 FALSE
3 B 1 FALSE
4 B 2 FALSE
我认为更简单的方法是
M$z <- with(M, (x == "A") & (y == 1))
M
x y z
1 A 1 TRUE
2 A 2 FALSE
3 B 1 FALSE
4 B 2 FALSE
【讨论】:
这是解决问题的一种更有效的方法。 @tfarkas 本机矢量化几乎总是比使用apply
更好。更简单:M$z<-ifelse((x == "A") & (y == 1), T, F)
为什么不只是M$z <- M$x == "A" & M$y == 1
? - 没关系...您的编辑基本上就是这样做的。我只是不喜欢整个 ifelse(conditional, T, F)
构造,因为无论如何你只是在输出条件中的内容。
从高效到极简主义!非常感谢大家。为什么我不能接受其中任何一个作为答案?作为记录,我最喜欢 ifelse() 构造,因为它计算效率高且通用(因此它可以输出任何模式的对象)。干杯!
@AriB.Friedman ifelse
并没有真正矢量化,就像apply()
等人一样。它正在对向量进行迭代,但它与使用 ==
和 &
的真正向量化操作不同,如对此答案的编辑所示。
ifelse
在我看来是矢量化的。它生成是和否结果的向量,并使用条件对其进行索引,因此这不是一种根本不同的方法。【参考方案2】:
看看mapply:
> M$z <- mapply(M$x,M$y, FUN=function(x,y) if((x == "A") && (y == 1)) T else F)
> M
x y z
1 A 1 TRUE
2 A 2 FALSE
3 B 1 FALSE
4 B 2 FALSE
恰巧,这与匿名函数无关,而与应用多个参数有关。如果您命名该函数,它仍然无法在任何单参数应用变体中工作。
另一种方法是按行发送ddply
,或者将您的 data.frame 拆分为一个列表,其中每一行都是一个单独的条目。
【讨论】:
我认为所有循环函数都有一个“...”参数,该参数将额外的参数传递给函数? @tfarkasmapply
也是如此。因为我已经为函数传递了一个参数名称,所以即使它位于第一个位置也匹配。然后其他所有内容都被包装到...
。以上是关于在 R 中使用带有多个参数的匿名函数的主要内容,如果未能解决你的问题,请参考以下文章