web-dev-qa-db-ja.com

lapply関数でリスト名にアクセスして保存する

Lapply関数内のリスト名にアクセスする必要があります。私はいくつかのスレッドをオンラインで見つけました。そこでは、関数の各リスト要素名を取得できるようにリストの名前を反復する必要があると言われています:

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

問題は、mynewlistが元のmylistインデックスを失い、それらを復元するためにそのlast names()割り当てを追加する必要があることです。

Lapply関数によって返される各要素に明示的なインデックス名を付ける方法はありますか?または、mynewlist要素に正しいインデックス名が設定されていることを確認する別の方法はありますか? lapplyがリスト要素をmylistと同じ順序で返さない場合、mynewlistのインデックス名が間違っている可能性があります。

48
Robert Kubrick

lapplyは、デフォルトでは、繰り返し処理するすべての名前属性を保持すると考えています。 myListの名前をnに保存すると、そのベクターには「名前」がなくなります。経由で追加した場合、

names(n) <- names(myList)

前と同様にlapplyを使用すると、目的の結果が得られます。

編集

私の脳は今朝少し霧がかかっています。以下に、おそらくより便利な別のオプションを示します。

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

lapplyにはUSE.NAMES引数、そして実際にsapplyのコードを見て、私が愚かであることに気付きました。これはおそらくより良い方法でした。

47
joran

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
38
Brian Diggs

パッケージplyrからllply()を調べましたか?

それはまさにあなたが求めているものです。 リストの各要素について、関数を適用し、結果をリストとして保持します。 llplyは、ラベルを保持することを除いてlapplyと同等ですで、進行状況バーを表示できます。from ?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"
6
Maiasaura

ジョランの答えに基づいて、それを正確にする:

sapply(USE.NAMES=T)ラッパーは、実際に反復するベクトルの値を最終結果の名前として設定します(lapplyのような名前属性ではなく)ただし、これらが文字の場合のみ =

結果として、インデックスを渡すことは役に立ちません。インデックスをsapplyで渡したい場合は、いくつかの(ugい)キャストに頼る必要があります。

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) 
6
Antoine Lizée

purrrパッケージのimap()は、問題に適しています。

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. 
2
Kevin Zarca