rbind()で困った点
データフレームにrbind
でアイテムを追加する場合、紹介されている例ではみな、データをベクトルで与えている(注:文字列型が勝手にFactor型にされてしまうのを4行目で回避している)。
1 2 3 4 5 6 7 8 9 10 |
> name <- c("alice") > age <- 26 > data <- data.frame(name = name, age = age) > data$name <- as.character(data$name) > > data <- rbind(data, c("john", 38)) > data name age 1 alice 26 2 john 38 |
一見するとうまくいっているが、実は問題がある。ageの項目が数字のはずだと内容を参照したり計算しようとすると・・・
1 2 3 4 5 6 |
> data[1, 2] [1] "26" > data[2, 2] [1] "38" > data[1, 2] + data[2, 2] data[1, 2] + data[2, 2] でエラー: 二項演算子の引数が数値ではありません |
となってしまう。
これはRのベクトルの仕様で、1つのベクトルの要素の型がすべて同じでなければならず、文字列型と数値型が混在した場合は数値が文字列に変換されてしまうため。
これを回避するために幾つかの方法があるが、たとえばここではas.numeric()
を用いてみる。
1 2 3 4 5 6 7 |
> data$age <- as.numeric(data$age) > data[1, 2] [1] 26 > data[2, 2] [1] 38 > data[1, 2] + data[2, 2] [1] 64 |
うむ、うまくいっている、と思って、これに新たなデータを追加すると・・・
1 2 3 4 5 6 7 8 9 10 11 12 |
> data <- rbind(data, c("luice", 30)) > data name age 1 alice 26 2 john 38 3 luice 30 > data[3, 2] [1] "30" > data[1, 2] [1] "26" > data[1, 2] + data[3, 2] data[1, 2] + data[3, 2] でエラー: 二項演算子の引数が数値ではありませ |
またしても怒られた。これはデータ追加のたびにベクトルの段階で文字列への変換が行われてしまうためらしく、上の9~10行目で前に数値型にしたはずのデータまで文字列に変換されてしまっている。
ベクトルではなくリストを使う
そこで、rbind
でデータ群を与えるのに、ベクトルではなくリストを使ってみた。
1 2 3 4 5 6 7 8 9 10 |
> name <- c("alice") > age <- 26 > data <- data.frame(name = name, age = age) > data$name <- as.character(data$name) > > data <- rbind(data, list("john", 38)) > data name age 1 alice 26 2 john 38 |
見た目はベクトルの時と同じく、うまくいっているように見える。そこで各要素をチェックしてみると・・・
1 2 3 4 5 6 |
> data[1, 2] [1] 26 > data[2, 2] [1] 38 > data[1, 2] + data[2, 2] [1] 64 |
ちゃんと数値として扱われている。それでは新たにデータを追加しても大丈夫か。
1 2 3 4 5 6 7 8 |
> data <- rbind(data, list("luice", 30)) > data name age 1 alice 26 2 john 38 3 luice 30 > data[1, 2] + data[3, 2] [1] 56 |
問題なし。
よって、文字列と数値が混在する場合は、rbind
の引数にはリストを使うべき。