2012-01-05 70 views
4
>>> [(x*y) for (x,y) in zip(range(3), (1,11,111))] 
[0, 11, 222]            

不喜欢这个R中改写这个列表理解

> 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]) 
} 
+0

所以,你想提供一个函数和一个列表,并使用模式匹配将函数应用到列表的元素? – 2012-01-05 16:40:27

回答

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比史蒂夫的mapply更好,因为它默认不简化,是更短的输入,并与记录其人页面上的其他功能功能打得很好,例如,ReduceFilterNegate)。

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

+0

好点重新:地图的优势,以弥补。 – 2012-01-05 17:25:37

+0

+1 +1 +1像这样...而不是搞乱v/l/apply,'Reduce'和'Filter'?!? Appetit ... – hhh 2012-01-06 03:26:06

+0

我甚至不知道Map/Reduce是否存在。这为非R用户提供了非常干净且众所周知的语法。 – zach 2014-06-04 19:45:28

1

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

我猜你想要的东西,如:

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

Josh的回答很有用,但是如果您想在Python上下文中为zip为您做的事情进行一些推广,请查看mapply,它可以同时“应用”几个“事物”,以及

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

和:从每一个“东西”,例如应用i个元素上的功能

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

更新:见马丁的回答,太:他使有关,如果你认为你是好点想要mapply ,您可能真的想要使用Map的便利。

+0

+1啊,如果我知道'zip'做了什么,它会有所帮助。 OP可能正在寻找'mapply'和/或'Map'。虽然在这个例子中'do.call'会更快,因为二进制函数是矢量化的。 – 2012-01-05 17:09:58