R言語を使う際に避けては通れない道であるデータフレームの操作について解説します。
データフレーム(data.frame)はデータセットを格納するための行列であり、データ解析をするうえで必要不可欠です。
この記事では、下記のデータフレームの基本的な操作:作成や値の参照・代入、行と列の追加や削除などを一通りまとめています。
この記事で学べる事
- データフレームの作成
- データフレームの参照
- データフレームの要素の取得
- データフレームの要素の変更
- 行名・列名の変更
- 行と列の追加・挿入・削除
- データフレームの結合
- データフレームの並び替え・ソート
- データフレームの転置(行と列の逆転)
- 欠測値の処理
- 行と列の合計・割合・平均・分散
- データフレームからピボットテーブルを作成
- データフレームのファイルへの保存
データ整形する際に必要な知識を網羅することができます。
この記事で扱うプログラミングコードは以下からダウンロードすることができます。テンプレートとして使ってもらって構いません。
R言語 データフレームの操作
ベクトルの操作方法については次の記事でまとめています。
【R言語】ベクトルの操作 作成・値の代入・要素の追加など
R言語のベクトルの操作(作成や参照、代入、要素の追加など)をまとめました。 この記事では以下のベクトルに関する操作を実行例付きで分かりやすく解説しています。 この記事で学べる事 ベクトルの作成 ベクト ...
続きを見る
データフレームの操作について見ていきます。作成や値の参照・代入、行と列の追加や削除だけでなくデータフレームのソートや欠測値などについてもまとめています。
実行例を全部載せた結果、ものすごい量になってしまったので複数のページに分けて操作方法を解説しています。
各ページの内容
を扱っています。
データフレームの作成
データフレームの作成するには関数data.frameを使います。
data.frameの引数を何も指定しない場合、0行0列のデータフレームのを作成することができます。
0行c列やr行0列のデータフレームする際は、関数matrixの引数nrowやncolをそれぞれrとcに指定した後に、[, 0]や[0, 1]で0列または0行の行列を作ります。この行列をdata.frameに渡すことで作成することができます。
1 2 3 4 5 6 7 8 9 10 | > #データフレームの作成 > data.frame() #0行0列のデータフレーム 0 列 0 行のデータフレーム > > data.frame(matrix(nrow = 3)[, 0]) #3行0列のデータフレーム 0 列 3 行のデータフレーム > > data.frame(matrix(ncol = 2)[0, ]) #0行2列のデータフレーム [1] X1 X2 <0 行> (または長さ 0 の row.names) |
引数にベクトルを複数並べることで、そのベクトルを列にもつデータフレームを作成することが可能です。また、行列の形を保ったままデータフレームに変換することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | > df1 <- data.frame(numbers = seq(1, 10), letters = letters[seq(1, 10)]) #ベクトルから作成 > df2 <- data.frame(matrix(seq(1, 10), nrow = 5)) #行列から作成 > df1 numbers letters 1 1 a 2 2 b 3 3 c 4 4 d 5 5 e 6 6 f 7 7 g 8 8 h 9 9 i 10 10 j > df2 X1 X2 1 1 6 2 2 7 3 3 8 4 4 9 5 5 10 |
データフレームの参照
データ解析をする前に、データセットがどのような変数から構成されているのか知りたいときがよくあります。
関数headとtailを用いることでデータフレームの先頭と末尾の要素を確認することが可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | > #データフレームの参照 > df1 <- data.frame(numbers = seq(1, 10), letters = letters[seq(1, 10)], + logicals = sample(c(TRUE, FALSE), 10, replace = TRUE), + dates = seq(Sys.Date(), by = "day", length.out = 10), + row.names = paste0("id:", seq(1, 10))) > head(df1) #先頭 numbers letters logicals dates id:1 1 a TRUE 2022-01-28 id:2 2 b FALSE 2022-01-29 id:3 3 c TRUE 2022-01-30 id:4 4 d FALSE 2022-01-31 id:5 5 e TRUE 2022-02-01 id:6 6 f FALSE 2022-02-02 > tail(df1) #末尾 numbers letters logicals dates id:5 5 e TRUE 2022-02-01 id:6 6 f FALSE 2022-02-02 id:7 7 g TRUE 2022-02-03 id:8 8 h FALSE 2022-02-04 id:9 9 i FALSE 2022-02-05 id:10 10 j FALSE 2022-02-06 |
また、次のように引数nを指定することで、どこまで参照するか指定することが可能です。
1 2 3 4 5 | > head(df1, 3) #位置を指定 numbers letters logicals dates id:1 1 a TRUE 2022-01-28 id:2 2 b FALSE 2022-01-29 id:3 3 c TRUE 2022-01-30 |
また、行名や列名を知りたいときはrownamesやcolnames、dimnamesを用います。以下、関数の概要です。
- rownamesで行名
- colnamesで列名
- dimnamesで行名と列名のリスト
また、次はrownamesとcolnamesの実行例です。
1 2 3 4 5 6 7 8 9 10 | > rownames(df1) #行名 [1] "id:1" "id:2" "id:3" "id:4" "id:5" "id:6" "id:7" "id:8" "id:9" "id:10" > colnames(df1) #列名 [1] "numbers" "letters" "logicals" "dates" > dimnames(df1) #次元名(行・列名) [[1]] [1] "id:1" "id:2" "id:3" "id:4" "id:5" "id:6" "id:7" "id:8" "id:9" "id:10" [[2]] [1] "numbers" "letters" "logicals" "dates" |
これらの関数を使うことでデータフレームがどのような変数から構成されているのか把握することができます。
データフレームの要素の取得
データフレームの要素の参照方法をいくつかに分けて紹介します。
後の要素の変更および代入で紹介しますが、データフレームの要素の参照には次の3通りの方法があります。
- インデックスで指定する方法
- 行名や列名で指定する方法
- 真偽値(logical型)で指定する方法
それぞれの利点を実行例とともに説明していきます。
インデックスで指定
まず、一番簡単な指定方法であるインデックスについて見ていきます。
データフレームdfの要素を参照する方法を次のリストにまとめました。
- 5行2列の要素を参照したいときは、df[5, 2]
- 3行目を取得したいときは,df[3, ]
- 3から5行目を取得したいときは、df[seq(3, 5), ]
- 2列目を取得したいときは、df[, 2]
- 1列目と2列目を取得したいときは、df[, c(1, 2)]
- 3から5行目かつ1と2行目を取得したいときは、df1[seq(3, 5), c(1, 2)]
上に示すように、行や列単位で取得したいときは、行や列に対応する要素を指定しないで参照したい行や列のインデックスを与えれば大丈夫です。
また、複数の行を取得したいときは、ベクトルを与えてあげます。
さらに、行と列にインデックスのベクトルを与えることで、データフレームのその行と列が交差する部分を取得することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | > df1 numbers letters logicals dates id:1 1 a TRUE 2022-01-28 id:2 2 b FALSE 2022-01-29 id:3 3 c TRUE 2022-01-30 id:4 4 d FALSE 2022-01-31 id:5 5 e TRUE 2022-02-01 id:6 6 f FALSE 2022-02-02 id:7 7 g TRUE 2022-02-03 id:8 8 h FALSE 2022-02-04 id:9 9 i FALSE 2022-02-05 id:10 10 j FALSE 2022-02-06 > > df1[5, 2] #5行目2列目 [1] "e" > > df1[3, ] #3行目 numbers letters logicals dates id:3 3 c TRUE 2022-01-30 > > df1[seq(3, 5), ] #3から5行目 numbers letters logicals dates id:3 3 c TRUE 2022-01-30 id:4 4 d FALSE 2022-01-31 id:5 5 e TRUE 2022-02-01 > > df1[, 2] #2列目 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" > > df1[, c(1, 2)] #1から2列目 numbers letters id:1 1 a id:2 2 b id:3 3 c id:4 4 d id:5 5 e id:6 6 f id:7 7 g id:8 8 h id:9 9 i id:10 10 j > > df1[seq(3, 5), c(1, 2)] #3から5行目, 1から2列目 numbers letters id:3 3 c id:4 4 d id:5 5 e |
インデックスで指定するのは簡単ですが、例えば解析するデータセットの列の順番が変わったり行の順番が変わってしまうと、いちいち書き直さなければいけないという手間がかかります。
また、全てインデックスで指定してしまうとプログラミングコードがマジックナンバーだらけになってしまい、何を描いているのか分かりません。
コードの質的にもよろしくないので、インデックスで指定する方法はあまりお勧めしません。
この次に紹介する名前で指定する方法や真偽値で指定する方法をお勧めします。
行名や列名で指定
続いて行名や列名で指定する方法について見ていきます。データセットに行名や列名があれば、上のインデックスで指定する方法を頼らずにすべての操作が可能です。
名前をプログラミングコードで書いているので、どこで何の処理を行っているのかパッと見分かりやすく、インデックスよりおススメです。この指定方法に慣れましょう。
行名や列名でデータフレームの要素を参照する方法を以下にまとめます。
- 行名"id:1"の行かつ列名"letters"を参照したいときは、df["id:1", "letters"]
- 行名"id:1"の行を取得したいときは、df["id:1", ]
- 行名"id:1"から"id:5"の行を取得したいときは、df[paste0("id:", seq(1, 5)), ]
- 列名"letters"の列を取得したいときは、df[, "letters"]
- 行名"id:1"から"id:5"の行かつ列名"numbers"と"letters"の列を取得したいときは、df[paste0("id:", seq(1, 5)), c("numbers", "letters")]
- 3から5行目かつ1と2行目を取得したいときは、df1[seq(3, 5), c(1, 2)]
インデックスのように参照したい行名や列名を与えることで参照が可能です。行名や列名1つのみでなく、ベクトルを与えることで複数の行と列を取得することもできます。
列に関してはdf$lettersのように、データフレームの後ろに$を付けて列を取得することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | > #名前で取得 > df1["id:1", ] #行 numbers letters logicals dates id:1 1 a TRUE 2022-01-28 > > df1$numbers #列 [1] 1 2 3 4 5 6 7 8 9 10 > > df1[, "numbers"] #列 [1] 1 2 3 4 5 6 7 8 9 10 > > df1["id:5", "letters"] #行名id:5かつ列名letters [1] "e" > > df1[paste0("id:", seq(1, 5)), ] #1から5行目 numbers letters logicals dates id:1 1 a TRUE 2022-01-28 id:2 2 b FALSE 2022-01-29 id:3 3 c TRUE 2022-01-30 id:4 4 d FALSE 2022-01-31 id:5 5 e TRUE 2022-02-01 > > df1[, c("numbers", "letters")] #1と2列目 numbers letters id:1 1 a id:2 2 b id:3 3 c id:4 4 d id:5 5 e id:6 6 f id:7 7 g id:8 8 h id:9 9 i id:10 10 j > > df1[paste0("id:", seq(1, 5)), c("numbers", "letters")] #1から5行目かつ1と2列目 numbers letters id:1 1 a id:2 2 b id:3 3 c id:4 4 d id:5 5 e |
真偽値で指定
データフレームのある条件を満たす要素を参照したいときに、真偽値で指定する方法が凄い便利です。
logical型のベクトルをデータフレームの大括弧の行と列に入れることで、logical型のTRUEの部分が交差する要素を参照することができます。何を言っているのか分からないと思うので、次の具体例で説明します。
2行目と3行目でlogical型のベクトルを与えています。データフレームのこのベクトルを与えると、1から5行目かつ1列目と2列目を取得することができました。
1 2 3 4 5 6 7 8 9 10 | > #真偽値で取得 > rows_logical <- c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) > cols_logical <- c(TRUE, TRUE, FALSE, FALSE) > df1[rows_logical, cols_logical] numbers letters id:1 1 a id:2 2 b id:3 3 c id:4 4 d id:5 5 e |
このようにTRUEであるインデックスの要素を参照することができます。これを用いることで次の特定の条件を満たすデータフレームの要素の参照が可能になります。この真偽値による指定は、例えばデータフレームにnumeric型の変数があって、「ある数値に等しい」または「a以上b以下」である行を取得したい場合に重宝します。
- 列numbersが5である行を取得したいときは、df[df$numbers == 5, ]
- numbersが3から7かつlettersが"d"または"f"である行を取得するときは、df[df1$numbers >= 3 & df1$numbers <= 7 & df1$letters == "d" | df1$letters == "f", ]
- 列名が"logicals"でない列を取得したいときは、df1[, colnames(df1) != "logicals"]
- 列名に"l"が含まれる列を取得するときは、df1[, grepl("l", colnames(df1))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | > df1[df1$numbers == 5, ] #numbersが5の行 numbers letters logicals dates id:5 5 e TRUE 2022-02-01 > > df1[df1$numbers >= 3 & df1$numbers <= 7, ] #numbersが3から7までの行 numbers letters logicals dates id:3 3 c TRUE 2022-01-30 id:4 4 d FALSE 2022-01-31 id:5 5 e TRUE 2022-02-01 id:6 6 f FALSE 2022-02-02 id:7 7 g TRUE 2022-02-03 > > df1[df1$numbers >= 3 & df1$numbers <= 7 & df1$letters == "d" | df1$letters == "f", ] #numbersが3から7かつlettersが"d"または"f"の行 numbers letters logicals dates id:4 4 d FALSE 2022-01-31 id:6 6 f FALSE 2022-02-02 > > df1[, colnames(df1) != "logicals"] #"logicals"でない列 numbers letters dates id:1 1 a 2022-01-28 id:2 2 b 2022-01-29 id:3 3 c 2022-01-30 id:4 4 d 2022-01-31 id:5 5 e 2022-02-01 id:6 6 f 2022-02-02 id:7 7 g 2022-02-03 id:8 8 h 2022-02-04 id:9 9 i 2022-02-05 id:10 10 j 2022-02-06 > > df1[, grepl("l", colnames(df1))] #列名に"l"が含まれる列 letters logicals id:1 a TRUE id:2 b FALSE id:3 c TRUE id:4 d FALSE id:5 e TRUE id:6 f FALSE id:7 g TRUE id:8 h FALSE id:9 i FALSE id:10 j FALSE |
データフレームの要素の変更
データフレームの要素の取得の3通りの方法を使うことでデータフレームの要素の変更が可能です。
インデックスでの指定、名前での指定、真偽値での指定の3通りの方法について見ていきます。
インデックスで指定
データフレームの5行目2列目を変更したいときは次のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | > df1 numbers letters logicals dates id:1 1 a FALSE 2022-01-28 id:2 2 b TRUE 2022-01-29 id:3 3 c FALSE 2022-01-30 id:4 4 d TRUE 2022-01-31 id:5 5 e TRUE 2022-02-01 id:6 6 f FALSE 2022-02-02 id:7 7 g TRUE 2022-02-03 id:8 8 h TRUE 2022-02-04 id:9 9 i FALSE 2022-02-05 id:10 10 j FALSE 2022-02-06 > > df1[5, 2] <- "abcdefg" #5行目1列目 > > df1 numbers letters logicals dates id:1 1 a FALSE 2022-01-28 id:2 2 b TRUE 2022-01-29 id:3 3 c FALSE 2022-01-30 id:4 4 d TRUE 2022-01-31 id:5 5 abcdefg TRUE 2022-02-01 id:6 6 f FALSE 2022-02-02 id:7 7 g TRUE 2022-02-03 id:8 8 h TRUE 2022-02-04 id:9 9 i FALSE 2022-02-05 id:10 10 j FALSE 2022-02-06 |
5行2列目の"e"が"abcdefg"に変更されているのが分かります。
行単位で要素を変更したい場合は、列のインデックスを指定せずに変更したい行のインデックスを与えればおkです。
次のコードの1行目でデータフレームの3行目を変更し、2行目では4から6行目を変更しています。複数の行を変更する際はベクトルを与えましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | > df1[3, ] <- c(1234, "hoge", FALSE, "2022-12-31") #3行目 > df1[seq(4, 6), ] <- data.frame(c(33, 44, 55), c("hoge1", "hoge2", "hoge3"), c(TRUE, FALSE, TRUE), + c("2022-12-29", "2022-12-30","2022-12-31")) #4から6行目 > > df1 numbers letters logicals dates id:1 1 a FALSE 2022-01-28 id:2 2 b TRUE 2022-01-29 id:3 1234 hoge FALSE 2022-12-31 id:4 33 hoge1 TRUE 2022-12-29 id:5 44 hoge2 FALSE 2022-12-30 id:6 55 hoge3 TRUE 2022-12-31 id:7 7 g TRUE 2022-02-03 id:8 8 h TRUE 2022-02-04 id:9 9 i FALSE 2022-02-05 id:10 10 j FALSE 2022-02-06 |
同様に、列単位での変更が可能です。次のコードの1行目でデータフレームの2列目の変更を、2行目で1と2列目の変更を行っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | > df1[, 2] <- paste0("hoge", seq(10)) #2列目 > df1[, seq(1, 2)] <- data.frame(seq(10, 100, 10), LETTERS[seq(10)]) #1から2列目 > > df1 numbers letters logicals dates id:1 10 A FALSE 2022-01-28 id:2 20 B TRUE 2022-01-29 id:3 30 C FALSE 2022-12-31 id:4 40 D TRUE 2022-12-29 id:5 50 E FALSE 2022-12-30 id:6 60 F TRUE 2022-12-31 id:7 70 G TRUE 2022-02-03 id:8 80 H TRUE 2022-02-04 id:9 90 I FALSE 2022-02-05 id:10 100 J FALSE 2022-02-06 |
行と列にベクトルのインデックスを与えることで次のようにデータフレームの一部を変更することができます。次を実行するとデータフレームの3から5行目かつ1と2列目が変更されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | > df1[seq(3, 5), seq(1, 2)] <- data.frame(c(33, 44, 55), c("hoge1", "hoge2", "hoge3")) #3から5行目, 1から2列目 > > df1 numbers letters logicals dates id:1 10 A FALSE 2022-01-28 id:2 20 B TRUE 2022-01-29 id:3 33 hoge1 FALSE 2022-12-31 id:4 44 hoge2 TRUE 2022-12-29 id:5 55 hoge3 FALSE 2022-12-30 id:6 60 F TRUE 2022-12-31 id:7 70 G TRUE 2022-02-03 id:8 80 H TRUE 2022-02-04 id:9 90 I FALSE 2022-02-05 id:10 100 J FALSE 2022-02-06 |
行名や列名で指定
次に、名前でデータフレームを変更する方法について紹介します。
行名でデータフレームを変更する際は、データフレームの行に行名を指定します。次を実行すると行名が"id:1"である行(1行目)が変更されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | > df1 numbers letters logicals dates id:1 10 A FALSE 2022-01-28 id:2 20 B TRUE 2022-01-29 id:3 33 hoge1 FALSE 2022-12-31 id:4 44 hoge2 TRUE 2022-12-29 id:5 55 hoge3 FALSE 2022-12-30 id:6 60 F TRUE 2022-12-31 id:7 70 G TRUE 2022-02-03 id:8 80 H TRUE 2022-02-04 id:9 90 I FALSE 2022-02-05 id:10 100 J FALSE 2022-02-06 > > df1["id:1", ] <- c(111, "aaa", TRUE, "2022-01-01") #行 > > df1 numbers letters logicals dates id:1 111 aaa TRUE 2022-01-01 id:2 20 B TRUE 2022-01-29 id:3 33 hoge1 FALSE 2022-12-31 id:4 44 hoge2 TRUE 2022-12-29 id:5 55 hoge3 FALSE 2022-12-30 id:6 60 F TRUE 2022-12-31 id:7 70 G TRUE 2022-02-03 id:8 80 H TRUE 2022-02-04 id:9 90 I FALSE 2022-02-05 id:10 100 J FALSE 2022-02-06 |
同様に列名で列を変更することができます。列名の場合はデータフレームの後ろに$をつけることで変更することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | > df1$numbers <- 100 * seq(1, 10) #列 > > df1 numbers letters logicals dates id:1 100 aaa TRUE 2022-01-01 id:2 200 B FALSE 2022-01-29 id:3 300 hoge1 FALSE 2022-12-31 id:4 400 hoge2 TRUE 2022-12-29 id:5 500 hoge3 FALSE 2022-12-30 id:6 600 F TRUE 2022-12-31 id:7 700 G FALSE 2022-02-03 id:8 800 H TRUE 2022-02-04 id:9 900 I FALSE 2022-02-05 id:10 1000 J FALSE 2022-02-06 > > df1[, "numbers"] <- rep(100, 10) #列 > > df1 numbers letters logicals dates id:1 100 aaa TRUE 2022-01-01 id:2 100 B FALSE 2022-01-29 id:3 100 hoge1 FALSE 2022-12-31 id:4 100 hoge2 TRUE 2022-12-29 id:5 100 hoge3 FALSE 2022-12-30 id:6 100 F TRUE 2022-12-31 id:7 100 G FALSE 2022-02-03 id:8 100 H TRUE 2022-02-04 id:9 100 I FALSE 2022-02-05 id:10 100 J FALSE 2022-02-06 |
また、ある行名と列名の2つを指定することで、それらの行と列が交差する要素を変更することが可能です。次は行名"id:5"かつ列名"letters"の要素の変更の例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | > df1["id:5", "letters"] <- "xyz" #行名id:5かつ列名letters > > df1 numbers letters logicals dates id:1 100 aaa TRUE 2022-01-01 id:2 100 B FALSE 2022-01-29 id:3 100 hoge1 FALSE 2022-12-31 id:4 100 hoge2 TRUE 2022-12-29 id:5 100 xyz FALSE 2022-12-30 id:6 100 F TRUE 2022-12-31 id:7 100 G FALSE 2022-02-03 id:8 100 H TRUE 2022-02-04 id:9 100 I FALSE 2022-02-05 id:10 100 J FALSE 2022-02-06 |
また次のように複数の行と列の変更も可能です。行名と列名のベクトルをデータフレームに与えることで、複数の行と列を変更することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | > df1[paste0("id:", seq(1, 5)), ] <- data.frame(rep(999, 5), rep("abcdef", 5), rep(TRUE, 5), rep("2022-01-01", 5)) #1から5行目 > > df1 numbers letters logicals dates id:1 999 abcdef TRUE 2022-01-01 id:2 999 abcdef TRUE 2022-01-01 id:3 999 abcdef TRUE 2022-01-01 id:4 999 abcdef TRUE 2022-01-01 id:5 999 abcdef TRUE 2022-01-01 id:6 100 F TRUE 2022-12-31 id:7 100 G TRUE 2022-02-03 id:8 100 H FALSE 2022-02-04 id:9 100 I TRUE 2022-02-05 id:10 100 J FALSE 2022-02-06 > > df1[, c("numbers", "letters")] <- data.frame(-seq(1, 10), LETTERS[seq(1, 10)]) #1と2列目 > > df1 numbers letters logicals dates id:1 -1 A TRUE 2022-01-01 id:2 -2 B TRUE 2022-01-01 id:3 -3 C TRUE 2022-01-01 id:4 -4 D TRUE 2022-01-01 id:5 -5 E TRUE 2022-01-01 id:6 -6 F TRUE 2022-12-31 id:7 -7 G TRUE 2022-02-03 id:8 -8 H FALSE 2022-02-04 id:9 -9 I TRUE 2022-02-05 id:10 -10 J FALSE 2022-02-06 |
行名と列名のベクトルを両方指定すると、次のようにその行名と列名に関する複数の要素変更することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | > df1[paste0("id:", seq(1, 5)), c("numbers", "letters")] <- data.frame(seq(1, 5), letters[seq(1, 5)]) #1から5行目かつ1と2列目 > > df1 numbers letters logicals dates id:1 1 a TRUE 2022-01-01 id:2 2 b TRUE 2022-01-01 id:3 3 c TRUE 2022-01-01 id:4 4 d TRUE 2022-01-01 id:5 5 e TRUE 2022-01-01 id:6 -6 F TRUE 2022-12-31 id:7 -7 G TRUE 2022-02-03 id:8 -8 H FALSE 2022-02-04 id:9 -9 I TRUE 2022-02-05 id:10 -10 J FALSE 2022-02-06 |
真偽値で指定
最後にlogical型で変更する方法について見ていきます。次のように、logical型のベクトルをデータフレームに与えるとTRUEの部分について変更することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | > #真偽値で代入 > rows_logical <- c(TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) > cols_logical <- c(TRUE, TRUE, FALSE, FALSE) > df1[rows_logical, cols_logical] <- data.frame(seq(2, 14, 3), letters[seq(2, 10, 2)]) > > df1 numbers letters logicals dates id:1 2 b TRUE 2022-01-01 id:2 5 d TRUE 2022-01-01 id:3 8 f TRUE 2022-01-01 id:4 11 h TRUE 2022-01-01 id:5 14 j TRUE 2022-01-01 id:6 -6 F TRUE 2022-12-31 id:7 -7 G TRUE 2022-02-03 id:8 -8 H TRUE 2022-02-04 id:9 -9 I TRUE 2022-02-05 id:10 -10 J FALSE 2022-02-06 |
また、「ある変数がaと等しい」行や「a以上b以下」である行の変更を行いたいときは、次のように論理演算をデータフレームの中で行えばおkです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | > df1[df1$numbers == 5, ] <- c(111, "aaa", TRUE, "2022-01-01") #numbersが5の行 > df1[df1$numbers >= 3 & df1$numbers <= 12, ] <- data.frame(rep(999, 5), rep("abcdef", 5), rep(TRUE, 5), rep("2022-01-01", 5)) #numbersが6から8までの行 > > df1 numbers letters logicals dates id:1 2 b TRUE 2022-01-01 id:2 111 aaa TRUE 2022-01-01 id:3 8 f TRUE 2022-01-01 id:4 11 h TRUE 2022-01-01 id:5 14 j TRUE 2022-01-01 id:6 -6 F TRUE 2022-12-31 id:7 -7 G TRUE 2022-02-03 id:8 -8 H TRUE 2022-02-04 id:9 -9 I TRUE 2022-02-05 id:10 -10 J FALSE 2022-02-06 |
次のように複雑な論理演算でも大丈夫です。次はnumbersが3から7かつlettersが"d"または"f"の行の変更を行っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | > df1[df1$numbers < 0 & df1$letters == "F" | df1$letters == "H", ] <- data.frame(rep(99999, 2), rep("abcdefgh", 2), rep(FALSE, 2), rep("2022-12-31", 2))#numbersが3から7かつlettersが"d"または"f"の行 > > df1 numbers letters logicals dates id:1 2 b TRUE 2022-01-01 id:2 111 aaa TRUE 2022-01-01 id:3 8 f TRUE 2022-01-01 id:4 11 h TRUE 2022-01-01 id:5 14 j TRUE 2022-01-01 id:6 99999 abcdefgh FALSE 2022-12-31 id:7 -7 G FALSE 2022-02-03 id:8 99999 abcdefgh FALSE 2022-12-31 id:9 -9 I FALSE 2022-02-05 id:10 -10 J FALSE 2022-02-06 |
同様に、列に関してもlogical型で変更できます。次では、列名が"logicals"でない列の変更と、列名に"l"が含まれている列の変更を行っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | > df1[, colnames(df1) != "logicals"] <- data.frame(seq(1, 10), letters[seq(1, 10)], seq(Sys.Date(), by = "day", length.out = 10)) #"logicals"でない列 > > df1 numbers letters logicals dates id:1 1 a TRUE 2022-01-28 id:2 2 b TRUE 2022-01-29 id:3 3 c TRUE 2022-01-30 id:4 4 d TRUE 2022-01-31 id:5 5 e TRUE 2022-02-01 id:6 6 f FALSE 2022-02-02 id:7 7 g FALSE 2022-02-03 id:8 8 h FALSE 2022-02-04 id:9 9 i FALSE 2022-02-05 id:10 10 j FALSE 2022-02-06 > > df1[, grepl("l", colnames(df1))] <- data.frame(rep("abc", 10), rep(TRUE, 10)) #列名に"l"が含まれる列 > > df1 numbers letters logicals dates id:1 1 abc TRUE 2022-01-28 id:2 2 abc TRUE 2022-01-29 id:3 3 abc TRUE 2022-01-30 id:4 4 abc TRUE 2022-01-31 id:5 5 abc TRUE 2022-02-01 id:6 6 abc TRUE 2022-02-02 id:7 7 abc TRUE 2022-02-03 id:8 8 abc TRUE 2022-02-04 id:9 9 abc TRUE 2022-02-05 id:10 10 abc TRUE 2022-02-06 |