リストに名前を付けるのは最後にした方がいいっぽい(へんなのR)
へんなのRというハッシュタグがある。
そこに投げつけるための話。
適当な関数の用意
3の時だけNULLであとはirisデータの頭を返す関数を用意する。
これはNULLを返す場合があるってのが本質で、あとは適当でよい。
#3の時だけNULLほかは適当 f <- function(i){ if(i==3){ NULL } else{ head(iris,i) } }
以下、この関数を適当にループさせ、その結果をリストに格納する形で使ってみる。
うまくいくケース
まずは何も考えずに使ってみたケース。
想像どおりの動き方&結果だ。
> x <- vector("list", 4) > for(i in 1:4){ + x[[i]] <- f(i) + } > x [[1]] Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa [[2]] Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa [[3]] NULL [[4]] Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa
うまくいかないケース
気を良くして、上のコードに一行、names(x)という処理を追加すると・・・名前がずれる。
> x <- vector("list", 4) > names(x) <- paste0("name", 1:4) > for(i in 1:4){ + x[[i]] <- f(i) + } > x $name1 Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa $name2 Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa $name4 NULL [[4]] Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa
原因と対策
にも書いてあるように、NULLを代入することは要素の削除と同義になっちゃうんでNGという話。
回避するには、この例だと最後に名前を割り当てるようにするか、あるいは汎用的な解決法としてはlapply使えと。
変なのー。