Как обновить элементы объектов в списке, используя lapply - PullRequest
1 голос
/ 10 марта 2020

У меня есть список с четырьмя объектами одинаковой длины. Я хочу обновить элементы объектов в соответствии с позициями элементов, хранящихся в векторе, которые соответствуют другому вектору, в котором хранятся имена объектов. Я могу сделать это с помощью для l oop, но мне интересно, как добиться того же результата, используя 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?

1 Ответ

2 голосов
/ 10 марта 2020

Мы можем split 'position' с помощью 'obj.names' и использовать Map для замены значений в 'mylist' на основе соответствующих list позиций элемента из split выходных данных

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

Или с использованием lapply с аналогичным циклом для unique 'obj.names', как в ОП for l oop

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