Доступ к именам списков и их сохранение в функции lapply - PullRequest
47 голосов
/ 27 февраля 2012

Мне нужно получить доступ к именам списков внутри функции lapply. Я нашел некоторые темы в Интернете, где сказано, что я должен перебирать имена списка, чтобы иметь возможность извлекать каждое имя элемента списка в моей функции:

> n = names(mylist)
> mynewlist = lapply(n, function(nameindex, mylist) { return(mylist[[nameindex]]) }, mylist)
> names(mynewlist)
NULL
> names(mynewlist) = n

Проблема в том, что mynewlist теряет исходные индексы mylist, и я должен добавить это назначение фамилии () для их восстановления.

Есть ли способ дать явное имя индекса каждому элементу, возвращаемому функцией lapply? Или другой способ убедиться, что элементы mynewlist имеют правильные имена индексов? Я чувствую, что имена индексов mynewlist могут быть неправильными, если lapply не возвращает элементы списка в том же порядке, что и mylist.

Ответы [ 5 ]

44 голосов
/ 27 февраля 2012

Я считаю, что lapply по умолчанию сохраняет атрибут имен того, что вы перебираете.Когда вы сохраняете имена myList в n, этот вектор больше не имеет никаких «имен».Поэтому, если вы добавите это обратно через

names(n) <- names(myList)

и используйте lapply, как и раньше, вы получите желаемый результат.

Редактировать

Сегодня утром у меня немного затуманено.Вот еще один, возможно, более удобный вариант:

sapply(n,FUN = ...,simplify = FALSE,USE.NAMES = TRUE)

Я нащупывал, смущенный тем, что lapply не имеет аргумента USE.NAMES, а затем я фактически посмотрел код для sapplyи понял, что я глупый, и, возможно, это был лучший путь.

37 голосов
/ 30 августа 2013

функция setNames - это полезный ярлык

mylist <- list(a = TRUE, foo = LETTERS[1:3], baz = 1:5)
n <- names(mylist)
mynewlist <- lapply(setNames(n, n), function(nameindex) {mylist[[nameindex]]})

который сохраняет имена

> mynewlist
$a
[1] TRUE

$foo
[1] "A" "B" "C"

$baz
[1] 1 2 3 4 5
7 голосов
/ 28 февраля 2012

Вы смотрели на llply() из пакета plyr?

Это именно то, что вы просите. Для каждого элемента списка примените функцию, сохраняя результаты в виде списка. llply эквивалентен lapply за исключением того, что он сохранит метки и может отображать индикатор выполнения. из ?llply

mylist <- list(foo1=1:10,foo2=11:20)
>names(mylist)
[1] "foo1" "foo2"
newlist<- llply(mylist, function(x) mean(x))

>names(newlist)
[1] "foo1" "foo2"
5 голосов
/ 29 августа 2013

Опираясь на ответ Джорана и уточняя его:

Оболочка sapply(USE.NAMES=T) действительно установит в качестве имен конечного результата значения вектора, по которому вы перебираете (а не атрибута имён, например, lapply), , но только если это символы.

В результате прохождение индексов не поможет. Если вы хотите передать индексы с sapply, вам нужно прибегнуть к некоторому (некрасивому) кастингу:

sapply(as.character(c(1,11)), function(i) TEST[[as.numeric(i)]], USE.NAMES = TRUE)

В этом случае более чистым решением является непосредственная установка и использование имен вашего исходного объекта. Вот исчерпывающий список решений:

TEST <- as.list(LETTERS[1:12])

### lapply ##
## Not working because no name attribute
lapply(c(1,11), function(i) TEST[[i]])

## working but cumbersome
index <- c(1,11)
names(index) <- index
lapply(index, function(i) TEST[[i]])

### sapply ##
## Not working because vector elements are not strings
sapply(c(1,11), function(i) TEST[[i]], simplify = F) 

## Working with the casting trick
sapply(as.character(c(1,11)), function(i) TEST[[as.numeric(i)]], simplify = F)

## Cleaner, using names with sapply:
names(TEST) <- LETTERS[26:15] 
sapply(names(TEST)[c(1,11)], function(name) TEST[[name]], simplify = F) 
2 голосов
/ 07 ноября 2017

imap() из пакета purrr подходит для вашей проблемы.

library(purrr)
mylist <- list(foo1=1:10,foo2=11:20)
imap(mylist, function(x, y) mean(x)) ## x is the value, y is the name

или вы можете использовать более компактную версию imap:

imap(mylist, ~ mean(.x))

Обратите внимание, что выможно использовать варианты imap_xxx в зависимости от типа нужного вам вектора:

imap_dbl(mylist, ~ mean(.x)) ## will return a named numeric vector. 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...