2015-04-27 48 views
1

我需要在保留原始結構的同時替換列表中的每個值。我有一個矢量。我需要在向量中找到大於或等於列表中每個值的最小值。然後用這個最小值替換列表中的值。該列表足夠長,循環無法工作。有沒有辦法通過應用程序或相關功能來執行此操作?In R如何在保留原始列表結構的同時替換長列表中的元素?

a <- list(x = 1, y = c(2,3), z = 5) 
b <- c(1,2,4,6,7) 

> a 
$x 
[1] 1 

$y 
[1] 2 3 

$z 
[1] 5 

我想生產什麼是改進型的,使得

> a 
$x 
[1] 1 

$y 
[1] 2 4 

$z 
[1] 6 

使用lapply我可以親近,

> lapply(unlist(a), function(x) min(b[b>=x])) 
$x 
[1] 1 

$y1 
[1] 2 

$y2 
[1] 4 

$z 
[1] 6 

但結構不再保留爲現在有一個$y1$y2而不是隻有兩個元素的$y

回答

1

relist()在列表'骨架'的形狀周圍包裹一個向量「肉」。因此,使用unlist(unname(a))來獲取值的向量(沒有名稱,正如您在示例中看到的那樣,構建起來是不合理的和昂貴的)。應用您的標準各單元(使用vapply(),這比你lapply更嚴格一點),然後用relist()恢復原來的形狀

v = unlist(unname(a)) 
result = vapply(v, function(x, b) min(b[b>=x]), numeric(1), b) 
relist(result, a) 

vapply()仍然是循環。一個更快的版本是使用findInterval(),像

i = findInterval(v, b) 
result = ifelse(b[i] == v, b[i], b[i + 1]) 

這就要求b排序(也可能是我沒有終點正確的)。

+0

太棒了!謝謝。我花了幾天的時間尋找一種方法來做到這一點。 – MattS

相關問題