データの解析において、複数のデータソースから情報を統合することは重要です。
この記事では、Rを使用してデータの結合(列の結合)を行う方法について紹介します。
データの結合は、データ解析において欠かせないステップです。今回は、列の結合(横の結合)を解説します。
1. 同じ行数で、異なる列名をもつデータ同士の列の結合 (cbind関数)
2. 行数が異なるデータの結合 (空のデータフレームをつくってcbind関数)
3. 共通の列名をもつデータの結合(merge関数が便利!)
1. 同じ行数で、異なる列名をもつデータ同士の列の結合(cbind関数)
同じ行数を持つ異なるデータを列で結合(横に結合)する方法を示します。
df1 <- data.frame(ID = 1:3, #3行×3列のデータフレームを作成
Name = c("John", "Alice", "Bob"),
Score = c(80, 75, 90))
df2 <- data.frame(Age = c(25, 30, 28), #3行×2列のデータフレームを作成
Grade = c("A", "B", "C"))
combined_df<-cbind(df1, df2)
combined_df
# ID Name Score Age Grade
#1 1 John 80 25 A
#2 2 Alice 75 30 B
#3 3 Bob 90 28 C
cbind関数で、横に結合できました。
行数が異なるデータ同士だとこちらのコードは通りません。。次の方法でやってみて下さい!
2. 行数が異なるデータの結合 (空のデータフレームをつくってcbind関数)
行数が異なるデータ同士を結合する場合は、上述のcbindでは、エラーが出てしまいます。。
そこで、行数の多いデータに合わせて空のデータフレームを作成し、cbindを実行する方法で実行します。
df3 <- data.frame(Age = c(25, 30),
Grade = c("A", "B"))
combined_df2<-cbind(df1, df3)
# data.frame(..., check.names = FALSE) でエラー:
# 引数に異なる列数のデータフレームが含まれています: 3, 2
n_rows <- nrow(df1) # df1が最大行数なので、df1の行数の空のデータフレーム(※)を作成
#最大行数が不明の場合は、n_rows <- max(nrow(df1), nrow(df3)) とすると、大きい行数で空のデータフレームを作成
empty_df3 <- data.frame(Age = rep(NA, n_rows), Grade = rep(NA, n_rows)) #df3の列名を※に入れる
empty_df3
# Age Grade
#1 NA NA
#2 NA NA
#3 NA NA
empty_df3[1:nrow(df3), ] <- df3 #空のデータフレームにデータを入れる
empty_df3
# Age Grade
#1 25 A
#2 30 B
#3 NA <NA> #3行目はないので、NAのまま
combined_df2<-cbind(df1, empty_df3) #結合
combined_df2
# ID Name Score Age Grade
#1 1 John 80 25 A
#2 2 Alice 75 30 B
#3 3 Bob 90 NA <NA>
行数がそろったデータ同士の列の結合ができました。
データがないところには欠損値としてNAが入ります。
次は、共通の列名の情報を基準としたデータ結合です!
3. 共通の列名をもつデータの結合 (merge関数が便利!)
同じ列名(キー)をもつデータの結合には、merge関数が便利です!
dplyrパッケージのinner_join関数(共通の行だけ残して結合)、left_join関数(左(先、x)のデータに右(後、y)のデータを結合(左にない行は消える))、などありますが、merge関数で同様の作業ができます!
①行情報と行数が揃ってる(行の順番変化はOK)場合(merge関数使用)
df1 <- data.frame(ID = c(1, 2, 3),
Name = c("John", "Alice", "Bob"),
Score = c(80, 75, 90))
df1
# ID Name Score
#1 1 John 80
#2 2 Alice 75
#3 3 Bob 90
df4 <- data.frame(ID = c(1, 3, 2),
Age = c(25, 30, 28),
Grade = c("A", "B", "C"))
df4
# ID Age Grade
#1 1 25 A
#2 3 30 B
#3 2 28 C
merged_df <- merge(df1, df4, by = "ID") #IDで揃える。
merged_df
# ID Name Score Age Grade
#1 1 John 80 25 A
#2 2 Alice 75 28 C
#3 3 Bob 90 30 B
②行情報や行数が揃ってない場合(merge関数使用)
◆共通する行だけ残す方法(inner_join関数と同じ)
df4 <- data.frame(ID = c(1, 2, 5),
Name = c("John", "Alice", "Sarah"),
Score = c(80, 75, 83))
df5 <- data.frame(ID = c(1, 3, 2, 4),
Age = c(25, 30, 28, 22),
Grade = c("A", "B", "C", "D"))
merged_df2 <- merge(df4, df5, by="ID") ※
merged_df2
# ID Name Score Age Grade
#1 1 John 80 25 A
#2 2 Alice 75 28 C
#inner_join(df4, df5, by="ID") で同じmerged_df2を作成
◆共通していない行も全部残す(情報がないところはNAで補完、all=TRUE使用、full_join関数と似てる)
merged_df3<-merge (df4, df5, by="ID", all = TRUE)
merged_df3
# ID Name Score Age Grade
#1 1 John 80 25 A
#2 2 Alice 75 28 C
#3 3 <NA> NA 30 B
#4 4 <NA> NA 22 D
#5 5 Sarah 83 NA <NA>
full_join(df4, df5, by="ID")
# ID Name Score Age Grade
#1 1 John 80 25 A
#2 2 Alice 75 28 C
#3 5 Sarah 83 NA <NA>
#4 3 <NA> NA 30 B
#5 4 <NA> NA 22 D #mergeとは順番が違うので注意
◆先データ(x)に後データ(y)を結合(先データにあるIDの行のみ残す、all.x=TRUE使用、left_join関数と同じ)
◆後データ(y)に先データ(x)を結合(後データにあるIDの行のみ残す、all.y=TRUE使用、right_join関数と同じ)
merged_df5<-merge (df4, df5, by="ID", all.x = TRUE) #先(df4, x)のデータに後(df5, y)のデータを結合。all.x=TRUEは、先のデータを全部残して、後のデータで先のデータと共通する"ID"の列のみを結合させる
merged_df5
# ID Name Score Age Grade
#1 1 John 80 25 A
#2 2 Alice 75 28 C
#3 5 Sarah 83 NA <NA>
# left_join(df4, df5, by="ID") 同じmerged_df5 を作成
merged_df6<-merge (df4, df5, by="ID", all.y = TRUE) #後(df5, y)のデータに先(df4, x)のデータを列結合。all.y=TRUEは、後のデータを全部残して、先のデータで後のデータと共通する"ID"の列のみを結合させる
merged_df6
# ID Name Score Age Grade
#1 1 John 80 25 A
#2 2 Alice 75 28 C
#3 3 <NA> NA 30 B
#4 4 <NA> NA 22 D
# right_join(df4, df5, by="ID") 同じmerged_df6 を作成
いろいろなパターンの列の結合を紹介しました。
作業で使用してみてください。
行の結合についても投稿していますので、こちらもご覧ください。
コメント