Edited at

列名で列を抽出したり列を削除したりする[R]

Rでデータセットを扱っていると、「この列だけ削除したい」、「この列とこの列だけ削除したい」ということが結構あります。列番号で指定して削除するのは簡単なのですが、列数が多いと列番号を数えるのも大変なので、列名で指定したい。いくつかあるようなのでまとめました。

例として、このデータセットを使います(テキトーに作ったものなので事実とは異なります笑)。studentsという変数で読み込んでhead()で最初の6行を見てみたのがこちら。

students <- read.csv("data/students.csv")

head(students)

  height income   area glasses gender university

1 153 341 Kansai YES male Keio
2 168 794 Kansai NO male Waseda
3 153 832 Kanto NO male Keio
4 188 721 Tohoku NO male Keio
5 175 840 Kanto NO male Waseda
6 156 1356 Kanto YES female Waseda


抽出するとき : 列番号も列名も使える


1列のみ抽出する

# 列番号で

students[, 3]

# 列名で
students[, "area"]
# どちらも結果は以下の通り
# [1] Kansai Kansai Kanto Tohoku Kanto Kanto Tohoku Kansai Kanto Tohoku
# [11] Kansai Kansai Kanto Kansai Tohoku Kansai Kanto Kanto Tohoku Kanto
# [21] Tohoku Kanto Kansai Tohoku Kanto Kansai Kansai Kanto Kanto Kanto
# [31] Kanto Tohoku Kanto Tohoku Kanto Kansai Kanto Kanto Kanto Kanto
# Levels: Kansai Kanto Tohoku


複数列をいっぺんに抽出する

# 列番号で

students[, c(3, 5)]

# 列名で
students[, c("area", "gender")]
# どちらも結果は以下の通り
# area gender
# 1 Kansai male
# 2 Kansai male
# 3 Kanto male
# 4 Tohoku male
# 5 Kanto male
# ... (省略)


削除するとき : 列番号は使えるが列名は使えない


1列のみ削除する

# 列番号で

students[, -3] # できる
# height income glasses gender university
# 1 153 341 YES male Keio
# 2 168 794 NO male Waseda
# 3 153 832 NO male Keio
# 4 188 721 NO male Keio
# 5 175 840 NO male Waseda
# ... (省略)

# 列名で
students[, -c("area")] # できない
# Error in -c("area") : invalid argument to unary operator


複数列をいっぺんに削除する

# 列番号で

students[, -c(3, 5)] # できる
# height income glasses university
# 1 153 341 YES Keio
# 2 168 794 NO Waseda
# 3 153 832 NO Keio
# 4 188 721 NO Keio
# 5 175 840 NO Waseda
# ... (省略)

# 列名で
students[, -c("area", "gender")] # できない
# Error in -c("area", "gender") : invalid argument to unary operator


列名で列を削除する

今の所見たことがあるやり方は、以下の2つです。


  • 差分を出してくれるsetdiff()を使うやり方


  • %in%を使うやり方


1列のみ削除する

# 差分を出してくれるsetdiff(データセット, ある列名)で「『ある列名』以外の列名」を指定

students[, setdiff(names(students), "area")]
# %in%を使う !(データセット %in% ある列名)で「『ある列名』以外の列名」を指定
students[, !(names(students) %in% "area")]

# どちらも結果は以下の通り
# height income glasses gender university
# 1 153 341 YES male Keio
# 2 168 794 NO male Waseda
# 3 153 832 NO male Keio
# 4 188 721 NO male Keio
# 5 175 840 NO male Waseda
# ... (省略)


複数列をいっぺんに削除する

# # 差分を出してくれるsetdiff(データセット, ある列名)で「『ある列名』以外の列名」を指定

students[, setdiff(names(students), c("area", "gender"))]
# %in%を使う !(データセット %in% ある列名)で「『ある列名』以外の列名」を指定
students[, !(names(students) %in% c("area", "gender"))]

# どちらも結果は以下の通り
# height income glasses university
# 1 153 341 YES Keio
# 2 168 794 NO Waseda
# 3 153 832 NO Keio
# 4 188 721 NO Keio
# 5 175 840 NO Waseda
# ... (省略)


まとめ



# 抽出するときと同じ感じで、列名で指定して列の削除はできない
students[, -c("area")] # できない
students[, -c("area", "gender")] # できない

# ので、
# 差分を出してくれるsetdiff()を使う
students[, setdiff(names(students), "area")]
students[, setdiff(names(students), c("area", "gender"))]
# %in%を使う
students[, !(names(students) %in% "area")]
students[, !(names(students) %in% c("area", "gender"))]

ちなみに、「列名の指定」を強調したくてデータフレーム [, 列名]としていたが、データフレーム [列名](カンマ省略)でも大丈夫。

students[3] # students[,3]と同じ

students["area"] # students[,"area"]と同じ
students[setdiff(names(students), "area")] #students[,setdiff(names(students), "area")]と同じ
students[!(names(students) %in% "area")] # students[,!(names(students) %in% "area")]と同じ