using anonymous functions in R with multiple arguments
我正在尝试在数据框中生成新变量,这些新变量以该数据框中的两个(或多个)其他变量为条件。我相信R中的循环函数(即lapply,sapply等)对于此目的是有用且高效的。但是,对于我的方法来说,有些事情是不正确的,我无法弄清楚是什么。
1
| M <- data.frame(x=c("A","A","B","B"), y=c(1,2,1,2)) |
使用此数据框,我想生成一个新列z,其中包含x =="A"和y == 1都为TRUE的逻辑。下面的代码是我在这里可以提出的最好的代码,但是似乎只能评估我的第一个条件。
1
| M$z <- sapply(M$x, function(x,y) if((x =="A") && (y == 1)) T else F, M$y) |
-
可以针对我的目的固定此代码吗?
-
在R中是否有更好的方法,也许可以使用其他循环函数?
这是transform函数
的任务
1 2 3 4 5 6
| 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 |
我认为更简单的方法是
1 2 3 4 5 6 7
| 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()等。它在向量上进行迭代,但与使用==和&进行真正的向量化操作不同,如对此答案的编辑中所示。
-
@GavinSimpson同意。路径依赖失败。
-
ifelse在我看来是矢量化的。它产生是和否结果的向量,并使用条件索引,因此没有根本不同的方法。
-
@ AriB.Friedman IMO,ifelse((x =="A") & (y == 1), T, F)太傻了。只要将TRUE和FALSE放在ifelse中,就表明您没有正确执行此操作。简单的&应该就可以了(或&& FWIW)。但是请注意,ifelse返回:一个向量,其长度和属性(包括尺寸和" " class "")与"测试"相同,并且数据值来自"是"或"否"。是的,它也适用长度强制。
看看mapply:
1 2 3 4 5 6 7
| > 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 |
Apropos,这与匿名函数无关,而与应用多个参数无关。如果您命名该函数,则在任何单参数apply变体中它仍然将不起作用。
另一种方法是按行ddply,或将data.frame拆分为一个列表,每行是一个单独的条目。
- 我认为所有循环函数都有一个" ... "参数,该参数将额外的参数传递给该函数?
-
@tfarkas mapply也是如此。由于Ive为该函数传递了一个参数名称,即使该参数位于第一个位置,该名称也将匹配。然后,其他所有内容都包裹在...中。