2012-02-27 2 views
34

lapply 함수 내부에서 목록 이름에 액세스해야합니다. 내 기능에서 각 목록 요소 이름을 가져올 수 있도록 목록의 이름을 반복해야했다 어디 내가 온라인 어떤 스레드를 발견했습니다lapply 함수에서 목록 이름 액세스 및 보존

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

문제는 mynewlist 원래 myList에 인덱스를 잃고 있다는 것입니다 및 그 마지막 이름() 과제를 추가하여 복원해야합니다.

lapply 함수가 반환 한 각 요소에 명시적인 인덱스 이름을 지정하는 방법이 있습니까? 또는 mynewlist 요소에 올바른 인덱스 이름이 설정되어 있는지 확인하는 다른 방법이 있습니까? lapply가 mylist와 같은 순서로 목록 요소를 반환하지 않으면 mynewlist 인덱스 이름이 잘못 될 수 있다고 생각합니다.

답변

33

기본적으로 lapply은 반복되는 모든 것의 names 속성을 유지한다고 생각합니다. myList의 이름을 n에 저장하면 해당 벡터에 더 이상 "이름"이 없습니다. 당신이 이전을 통한에서 그 뒤로,

names(n) <- names(myList) 

및 사용 lapply를 추가 그래서, 당신은 원하는 결과를 얻을 수 있습니다. 오늘 아침에 약간 안개

편집

내 두뇌. 여기에 아마도 더 편리, 또 다른입니다 옵션 :

sapply(n,FUN = ...,simplify = FALSE,USE.NAMES = TRUE) 
내가 lapplyUSE.NAMES 인수를하지 않았고, 나는 실제로 sapply의 코드를 보면서 내가 바보 인 것을 깨달았다, 그 혼란에 대해 모색했다

이것은 아마도 더 좋은 방법이었을 것입니다.

+0

네를, 이 작품. 나는 여전히 n = names (myList)를 통해 'n'을 생성해야합니다. 이름을 두 번 호출 (myList)하고, n을 만들려면 한 번, n 개의 속성을 두 번째로 설정합니다. –

+1

두 번째를'names (n) <- n'으로 대체 할 수 있습니다. – Aaron

+0

@RobertKubrick 가능한 경우 더 나은 해결책을 찾기 위해 편집하십시오. 'sapply'에 대한 코드가 얼마나 단순한 지 확인하십시오. 사실 이후에 이름을 추가하는 래퍼 역할을합니다. – joran

5

plyr에서 llply()을 들여다 보았습니까?

정확히 무엇을 요구하고 있습니까? 목록의 각 요소에 대해 함수를 적용하여 결과를 목록으로 유지합니다. llply는 라벨을 보존하고 진행률 표시 줄을 표시 할 수 있다는 점을 제외하면 lapply와 동일합니다. joran의 대답에 건물, 그것을 precising

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" 
+0

흠. 'lapply'와 정확히 똑같아 보입니다. 예를 들어'lapply (mylist, mean)'과'llply (names (mylist), function (x) mean (mylist [[x]]))'를 참조하십시오. "레이블 보존"이란 무엇을 의미합니까? – Aaron

+0

나는'mlply'가 이것을 할 것이라고 생각한다. – baptiste

4

?llply에서 :

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) 
32

setNames 기능은 purrr 패키지에서 이름을

> mynewlist 
$a 
[1] TRUE 

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

$baz 
[1] 1 2 3 4 5 
1

imap()을 유지 여기에 유용한 바로 가기

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

귀하에 대한 좋은됩니다 : 여기에 솔루션의 전체 목록입니다 문제.

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. 
관련 문제