在R中如何在保留原始列表结构的同时替换长列表中的元素?

时间:2015-04-27 19:35:22

标签: r

我需要替换列表中的每个值,同时保留原始结构。我有一个矢量。我需要在向量中找到大于或等于列表中每个值的最小值。然后使用此最小值替换列表中的值。列表足够长,循环不起作用。使用apply或相关函数有没有办法做到这一点?

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 个答案:

答案 0 :(得分: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进行排序(可能我没有得到正确的结束点)。