首页 > 解决方案 > 如何使用 lapply 更新列表中对象的元素

问题描述

我有一个包含四个长度相等的对象的列表。我想根据存储在向量中的元素位置更新对象的元素,该向量对应于存储对象名称的另一个向量。我可以使用 for 循环来做到这一点,但我想知道如何使用lapply(). 我尝试了各种尝试,但都没有成功。任何帮助是极大的赞赏。MWE如下:

编辑

列表中的四个对象是我在原始列表中的许多其他对象的示例。在我的原始列表中,并非所有对象都被选中。所以obj.names现在只采样三个字母来表示这一点。

obj.length <- 20
mylist <- list(a = rep(0, obj.length),
               b = rep(0, obj.length),
               c = rep(0, obj.length),
               d = rep(0, obj.length))

set.seed(27)
position <- sample(1:obj.length, 10)                         # elements to update
obj.names <- sample(letters[1:3], 10, replace = TRUE)        # corresponding object names for which the elements need to updated

for(i in unique(obj.names)){                                 # achieved here
  mylist[[i]][position[obj.names == i]] <- 99 
}

lapply(...)                                                  # but what to do here in order to achieve the same result as in for loop?

标签: rlistlapply

解决方案


我们可以split通过 'obj.names' 的 'position' 并根据输出中的相应元素位置Map来替换 'mylist' 中的值listsplit

newlist <- split(position, obj.names)
mylist[names(newlist)] <- Map(`[<-`, mylist[names(newlist)], newlist, 99)
mylist
#$a
# [1] 99  0  0  0 99  0  0  0  0  0  0  0  0  0  0  0  0  0 99  0

#$b
# [1]  0  0 99  0  0  0  0  0  0  0  0  0  0  0 99  0  0  0  0  0

#$c
# [1]  0  0  0  0  0  0  0 99 99  0  0  0 99 99  0  0  0 99  0  0

#$d
# [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

或者在'obj.names'上使用lapply与 OP 循环中类似的循环uniquefor

mylist[unique(obj.names)] <- lapply(unique(obj.names), function(nm) {
       mylist[[nm]][position[obj.names == nm]] <- 99
       mylist[[nm]]
        })
mylist

推荐阅读