在 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&lt;-ifelse((x == "A") &amp; (y == 1), T, F) 为什么不只是M$z &lt;- M$x == "A" &amp; M$y == 1? - 没关系...您的编辑基本上就是这样做的。我只是不喜欢整个 ifelse(conditional, T, F) 构造,因为无论如何你只是在输出条件中的内容。 从高效到极简主义!非常感谢大家。为什么我不能接受其中任何一个作为答案?作为记录,我最喜欢 ifelse() 构造,因为它计算效率高且通用(因此它可以输出任何模式的对象)。干杯! @AriB.Friedman ifelse 并没有真正矢量化,就像apply() 等人一样。它正在对向量进行迭代,但它与使用 ==&amp; 的真正向量化操作不同,如对此答案的编辑所示。 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 拆分为一个列表,其中每一行都是一个单独的条目。

【讨论】:

我认为所有循环函数都有一个“...”参数,该参数将额外的参数传递给函数? @tfarkas mapply 也是如此。因为我已经为函数传递了一个参数名称,所以即使它位于第一个位置也匹配。然后其他所有内容都被包装到...

以上是关于在 R 中使用带有多个参数的匿名函数的主要内容,如果未能解决你的问题,请参考以下文章

Python中的匿名函数——lambda函数

使用匿名函数作为参数访问外部变量

匿名函数

python函数 | 匿名函数

Python函数之匿名函数

6-1:递归内置函数匿名函数