2012-02-27 3 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は反復処理の名前属性を保持していると思います。 myListの名前をnに格納すると、そのベクターには「名前」がなくなります。あなたは、経由で

names(n) <- names(myList) 

前と同じように使用lapplyをそのバックを追加するのであれば、あなたは望ましい結果を取得する必要があります。今朝少し霧

編集

私の脳。 、私が模索された

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

lapplyUSE.NAMES引数を持っていなかった、そして私が実際にsapplyためのコードを見て、私は愚かされていたが実現することを混同し、:ここでは別の、おそらくより便利に、オプションですこれはおそらくより良い方法でした。

+0

うんを、これは機能します。私はまだn = names(myList)を介して 'n'を作成する必要があります。名前を2回呼び出す(myList).1回はnを作成し、2回はn個の属性を設定する。 –

+1

あなたは 'names(n)< - n'で2番目の文字を置き換えることができます。 – 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

Hmm。それはちょうど '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_xxxのバリエーションを使用することができます

imap(mylist, ~ mean(.x)) 

注:

imap_dbl(mylist, ~ mean(.x)) ## will return a named numeric vector. 
関連する問題