我需要替换列表中的每个值,同时保留原始结构。我有一个矢量。我需要在向量中找到大于或等于列表中每个值的最小值。然后使用此最小值替换列表中的值。列表足够长,循环不起作用。使用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
。
答案 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
进行排序(可能我没有得到正确的结束点)。