将这个列表推导式改写成R语言

4
>>> [(x*y) for (x,y) in zip(range(3), (1,11,111))]
[0, 11, 222]                                             

不要这样做

> data.frame(0:2,c(1,11,111))
  X0.2 c.1..11..111.
1    0             1
2    1            11
3    2           111
> data.frame(0:2,c(1,11,111))->a
> a[1]*a[2]
  X0.2
1    0
2   11
3  222

但是类似这样的东西。
lapply(a, function(x)
{   ...how can I access here the parameters of x? 
    (not using x[1] or x[2])
}

你想提供一个函数和一个列表,并使用模式匹配将函数应用于列表的元素吗? - Chris Taylor
3个回答

15

对于一般的模式,也许

Map(`*`, 0:2, c(1, 11, 111))
或者
unlist(Map(`*`, 0:2, c(1, 11, 111)))
更明确地说
Map(function(x, y) x*y, 0:2, c(1, 11, 111))

我喜欢Map胜过Steve的mapply,因为它默认不进行简化,键入更短,并且与其他在其手册中记录的函数(例如ReduceFilterNegate)相互配合。

对于这个特定问题的早期答案已被删除,只是0:2 * c(1, 11, 111),这将更有效率。


像这样+1 +1 +1,而不是搞乱v/l/apply、ReduceFilter!?胃口大开... - hhh
我甚至不知道Map/Reduce的存在。它为非R用户提供了一个非常干净、熟悉的语法。 - zach

6

Josh的回答十分准确,但如果你想对Python上下文中zip的常规化进行一些概述,请看一下mapply,它可以同时"应用"多个"东西",并将函数应用于每个"东西"的第i个元素,例如:

x1 <- 0:2
x2 <- c(1, 11, 111)
mapply(function(x, y) x*y, x1, x2)
## [1]   0  11 222

并且:

x3 <- c(10, 20, 30)
mapply(function(x, y, z) x * y + z, x1, x2, x3)
## [1]  10  31 252

更新:请见马丁的回答,他提出了一个很好的观点,如果你认为你需要 mapply,你可能更应该使用 Map 的便利性。

+1 啊,如果我知道zip是什么就好了。 OP可能在寻找mapply和/或Map。 虽然在这个例子中使用do.call会更快,因为二元函数是矢量化的。 - Joshua Ulrich

1

我不太清楚你的问题。 lapply 循环遍历列表的元素。因此,您的匿名函数将应用于 a 的每一列,但您的示例似乎表明您想将二元函数应用于两列。

我猜你想要这样的东西:

do.call("*",a)
# [1]   0  11 222

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接