Список именованных векторов из списка тиблей в R - PullRequest
0 голосов
/ 02 октября 2018

У меня, казалось бы, очень простая задача, но я не могу понять, что я делаю неправильно.У меня есть список из трех блоков Xx2 (в примере 2x2), имеющих символьный вектор и целочисленный вектор.Я хочу преобразовать его в список из 3 именованных векторов, где буквы - это векторные элементы, а цифры - это имена.Вот мой подход:

tbl <- tibble(numbers=c(1:2), letters=letters[1:2])
vec_names <- c("name1", "name2", "name3")
lst <- list(tbl, tbl, tbl)
names(lst) <- vec_names
lst_n <- lapply(lst, function(x) x[["letters"]]) 
lst_n <- sapply(vec_names, 
    function(x) names(lst_n[[x]]) <- lst[[x]]$numbers)

Я получаю этот результат

lst_n
     name1 name2 name3
[1,]     1     1     1
[2,]     2     2     2

и не вижу своей ошибки.Выполнение

names(lst_n[["name1"]]) <- lst[["name1"]]$numbers

дает мне именно то, что я хочу для "name1", но почему оно не работает с sapply?

Я имел [] раньше и изменил его на [[]] наполучить доступ к тибблам внутри списка вместо элементов списка, но это все равно не работает.Кто-нибудь может помочь?Это кажется очень простой задачей.

1 Ответ

0 голосов
/ 02 октября 2018

Вот один способ сделать это, все в одной анонимной функции:

z = lapply(lst, function(x) {
  result = x$letters
  names(result) = x$numbers
  return(result)
})

str(z)
# List of 3
#  $ name1: Named chr [1:2] "a" "b"
#   ..- attr(*, "names")= chr [1:2] "1" "2"
#  $ name2: Named chr [1:2] "a" "b"
#   ..- attr(*, "names")= chr [1:2] "1" "2"
#  $ name3: Named chr [1:2] "a" "b"
#   ..- attr(*, "names")= chr [1:2] "1" "2"

Ваш подход застрял, потому что после того, как вы извлекли все letters, вам нужно перебрать оба letters и numbers для установки имен, но lapply позволяет перебирать только одну вещь.(И присвоение внутри lapply не работает должным образом, единственное, что имеет значение, это возвращаемый объект.)

Если вы не можете использовать подход, описанный выше, выполнение действий водин проход через lst, вместо этого вы можете использовать Map, который перебирает несколько списков.Мы будем использовать функцию setNames вместо names<-(), которая вызывается при попытке сделать names(x) <-.

Map(
  f = setNames,
  object = lapply(lst, "[[", "letters"),
  nm = lapply(lst, "[[", "numbers")
)
# $`name1`
#   1   2 
# "a" "b" 
# 
# $name2
#   1   2 
# "a" "b" 
# 
# $name3
#   1   2 
# "a" "b" 
...