Установите для второго элемента вложенного списка имя элемента списка (purrr). - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть именованный список списков с пустыми элементами, которые я хочу заполнить:

List of 3
 $ name1:List of 3
  ..$ A: NULL
  ..$ B: NULL
  ..$ C: NULL
 $ name2:List of 3
  ..$ I: NULL
  ..$ J: NULL
  ..$ K: NULL
 $ name3:List of 3
  ..$ P: NULL
  ..$ Q: NULL
  ..$ R: NULL

Я могу назначить вектор, скажем, второму элементу каждого подсписка:

testlist <- map(testlist, ~modify_at(.x, 2, ~c("one", "two", "three")))
str(testlist)

List of 3
 $ name1:List of 3
  ..$ A: NULL
  ..$ B: chr [1:3] "one" "two" "three"
  ..$ C: NULL
 $ name2:List of 3
  ..$ I: NULL
  ..$ J: chr [1:3] "one" "two" "three"
  ..$ K: NULL
 $ name3:List of 3
  ..$ P: NULL
  ..$ Q: chr [1:3] "one" "two" "three"
  ..$ R: NULL

Но теперь я хочу назначить имя каждого элемента списка третьему элементу каждого подсписка (т. Е. Имя этого элемента будет отличаться при каждом повороте цикла).Желаемый результат:

List of 3
 $ name1:List of 3
  ..$ A: NULL
  ..$ B: NULL
  ..$ C: chr "name1"
 $ name2:List of 3
  ..$ I: NULL
  ..$ J: NULL
  ..$ K: chr "name2"
 $ name3:List of 3
  ..$ P: NULL
  ..$ Q: NULL
  ..$ R: chr "name3"

И простая модификация предыдущей функции не работает:

map(testlist, ~modify_at(.x, 3, ~.x))

Когда я это делаю, третий элемент каждогоподсписок полностью исчезает:

List of 3
 $ name1:List of 2
  ..$ A: NULL
  ..$ B: NULL
 $ name2:List of 2
  ..$ I: NULL
  ..$ J: NULL
 $ name3:List of 2
  ..$ P: NULL
  ..$ Q: NULL

Я пробовал различные комбинации, включая set_names (.x) или даже map2:

map2(testlist, names(testlist), ~modify_at(.x, 3, ~.y))

(последний битэквивалентно imap)

Но ничего не работает, и многие из них приводят к удалению третьего элемента каждого подсписка.И в названии основного списка нет ничего плохого.

names(testlist)
[1] "name1" "name2" "name3"

Я не совсем уверен, что там происходит.Будем благодарны за любые советы и помощь.

1 Ответ

0 голосов
/ 25 сентября 2019

По аналогии с R - составные функции по сравнению с конвейерными функциями в `purrr :: map ()` , легче увидеть, что происходит, когда вы используете анонимные функции, а не формула (~).

Начните с

testlist  <- list(name1=list(NULL,NULL,NULL), name2=list(NULL,NULL,NULL),
name3=list(NULL,NULL,NULL))

str(testlist)
#> List of 3
#>  $ name1:List of 3
#>   ..$ : NULL
#>   ..$ : NULL
#>   ..$ : NULL
#>  $ name2:List of 3
#>   ..$ : NULL
#>   ..$ : NULL
#>   ..$ : NULL
#>  $ name3:List of 3
#>   ..$ : NULL
#>   ..$ : NULL
#>   ..$ : NULL

Затем, чтобы воссоздать ваш первый пример, testlist2 <- map(testlist, ~modify_at(.x, 2, ~c("one", "two", "three"))) можно переписать как testlist2_expand <- map(testlist, function(x) modify_at(x, 2, function(y) y=c("one", "two", "three"))), что дает тот же результат для str(testlist2_expand) из

#> List of 3
#>  $ name1:List of 3
#>   ..$ : NULL
#>   ..$ : chr [1:3] "one" "two" "three"
#>   ..$ : NULL
#>  $ name2:List of 3
#>   ..$ : NULL
#>   ..$ : chr [1:3] "one" "two" "three"
#>   ..$ : NULL
#>  $ name3:List of 3
#>   ..$ : NULL
#>   ..$ : chr [1:3] "one" "two" "three"
#>   ..$ : NULL

Но ваш второй пример map(testlist, ~modify_at(.x, 3, ~.x)) действительно map(testlist, function(x) modify_at(x, 1, function (y) y = y))

Я думаю, вы ожидали повторного использования .x, но это новая переменная в новой области видимости.Он никогда не определяется, поэтому оценивается как NULL, что приводит к map(testlist, function(x) modify_at(x, 1, function (y) NULL)), а элемент удаляется

Чтобы сделать то, что вы хотите

testlist2 <- map2(testlist, names(testlist), function(x,y) modify_at(x, 3, function (z) z = y))
str(testlist2)
#> List of 3
#>  $ name1:List of 3
#>   ..$ : NULL
#>   ..$ : NULL
#>   ..$ : chr "name1"
#>  $ name2:List of 3
#>   ..$ : NULL
#>   ..$ : NULL
#>   ..$ : chr "name2"
#>  $ name3:List of 3
#>   ..$ : NULL
#>   ..$ : NULL
#>   ..$ : chr "name3"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...