現在很多數據資料都存放在資料庫中,分析有時需要其他的數據做為比對,參考,甚至一併使用,如何正確合併數據也成為很重要的事情,base包內也有類似的合併函數,在這裡一併拿來做個基本比對。
基本語法
bind_rows(dataset, dataset..)
bind_cols(dataset, dataset..)
base包的合併語法
rbind(dataset, deparse.level = 1…)
cbind(dataset, deparse.level = 1…)
merge(dataset1, dataset2)
dplyr的bind系列,有些規範,如果是照clos合併,rows就會按照名稱進行匹配,有缺失的就補上NA,如果照rows合併,clos就會按照位置匹配,所以要有相同的col數,來看一下基本合併的方式
# 建立同樣都是1 X 5的數據框
bind_df_1 <- tibble(c(1, 2, -3, 4, -5))
bind_df_2 <- tibble(c("ap", "ef", "tg", "hk", "bu"))
# 按照行合併
col_df <-
bind_cols(bind_df_1, bind_df_2)
# 輸出結果
r$> col_df
# A tibble: 5 x 2
`c(1, 2, -3, 4,
-5)` `c("ap", "ef", "tg", "hk",
"bu")`
<dbl> <chr>
1
1 ap
2
2 ef
3
-3 tg
4
4 hk
5
-5 bu
# 按照列合併
row_df <- bind_rows(bind_df_1,
bind_df_2)
r$> row_df
# A tibble: 10 x 2
`c(1, 2, -3, 4,
-5)` `c("ap", "ef", "tg", "hk",
"bu")`
<dbl> <chr>
1 1 NA
2 2 NA
3 -3 NA
4 4 NA
5 -5 NA
6 NA ap
7 NA ef
8 NA tg
9 NA hk
10
NA bu
當有複數的數據集進行合併時,沒有設定欄位標籤時,只有出現型態。
bind_df_1 <- tibble(c(1, 2, -3, 4, -5))
bind_df_2 <- tibble(c("ap", "ef", "tg", "hk", "bu"))
bind_df_3 <- tibble(c(22.3, 57.1, 69.4, 12.7, 70.34))
bind_df_4 <- tibble(c("Sunday", "Wednesday", "Monday", "Friday", "Saturday"))
# 按照行合併
cols_df <- bind_cols(bind_df_1, bind_df_2, bind_df_3, bind_df_4)
r$> cols_df
# A tibble: 5 x 4
`c(1, 2, -3, 4, -5)` `c("ap", "ef", "t~ `c(22.3, 57.1, 69.~ `c("Sunday", "Wedne~
<dbl> <chr> <dbl> <chr>
1 1 ap 22.3 Sunday
2 2 ef 57.1 Wednesday
3 -3 tg 69.4 Monday
4 4 hk 12.7 Friday
5 -5 bu 70.3 Saturday
# 按照列合併
rows_df <- bind_rows(bind_df_1, bind_df_2, bind_df_3, bind_df_4)
r$> rows_df
# A tibble: 20 x 4
`c(1, 2, -3, 4, -5)` `c("ap", "ef", "t~ `c(22.3, 57.1, 69~ `c("Sunday", "Wedne~
<dbl> <chr> <dbl> <chr>
1 1 NA NA NA
2 2 NA NA NA
3 -3 NA NA NA
4 4 NA NA NA
5 -5 NA NA NA
6 NA ap NA NA
7 NA ef NA NA
8 NA tg NA NA
9 NA hk NA NA
10 NA bu NA NA
11 NA NA 22.3 NA
12 NA NA 57.1 NA
13 NA NA 69.4 NA
14 NA NA 12.7 NA
15 NA NA 70.3 NA
16 NA NA NA Sunday
17 NA NA NA Wednesday
18 NA NA NA Monday
19 NA NA NA Friday
20 NA NA NA Saturday
若是不同大小的合併,不同col數就無法合併了,但由此也可以知道,合併後或多或少會產生NA值,除非整個數據集大小完全相同,就看後續怎麼進行NA值的處理了
bind_df_1 <- tibble(c(1, 2, -3, 4, -5))
bind_df_5 <- tibble(c(123, 246, -334, 455, -51, 24, 223, 644))
col_df <- bind_cols(bind_df_1, bind_df_5)
r$> col_dfdf <- bind_cols(bind_df_1, bind_df_5)
Error: Can't recycle `..1` (size 5) to match `..2` (size 8).
Run `rlang::last_error()` to see where the error occurred.
# 按照列合併
rows_df <- bind_rows(bind_df_1, bind_df_5)
# 輸出結果
r$> rows_df
# A tibble: 13 x 2
`c(1, 2, -3, 4, -5)` `c(123, 246, -334, 455, -51, 24, 223, 644)`
<dbl> <dbl>
1 1 NA
2 2 NA
3 -3 NA
4 4 NA
5 -5 NA
6 NA 123
7 NA 246
8 NA -334
9 NA 455
10 NA -51
11 NA 24
12 NA 223
13 NA 644
若是base包內的合併函數
rbind() >> 需要有相同的列才能合併,合併後依序延伸下去
cbind() >> 將不同的行進行合併,合併後產生新的行,可以多個數據集合併
bind_df_1 <- tibble(
number = c(1, 2, -3, 4, -5)
)
bind_df_2 <- tibble(
letter = c("ap", "ef", "tg", "hk", "bu")
)
bind_df_3 <- tibble(
number = c(22.3, 57.1, 69.4, 12.7, 70.34)
)
rbind(bind_df_1, bind_df_2)
# 輸出結果 >> 沒有相同欄位無法合併
r$> rbind(bind_df_1, bind_df_2)
Error in match.names(clabs, names(xi)) : 名稱同原來已有的名稱不相對
# 使用base包內的cbind函數
cbind(bind_df_1, bind_df_2)
r$> cbind(bind_df_1, bind_df_2)
number letter
1 1 ap
2 2 ef
3 -3 tg
4 4 hk
5 -5 b
# 同樣有number欄位
rbind(bind_df_1, bind_df_3)
r$> rbind(bind_df_1, bind_df_3)
# A tibble: 10 x 1
number
<dbl>
1 1
2 2
3 -3
4 4
5 -5
6 22.3
7 57.1
8 69.4
9 12.7
10 70.3
# 同樣有number欄位
cbind(bind_df_1, bind_df_3)
r$> cbind(bind_df_1, bind_df_3)
number number
1 1 22.30
2 2 57.10
3 -3 69.40
4 4 12.70
5 -5 70.34
最後看一下base包內的merge函數,merge有數據數量限制,一次只能兩個數據集合併,合併後會進行對應擴充,若是名稱相同則無法合併
merge(bind_df_1, bind_df_2)
r$> merge(bind_df_1, bind_df_2)
number letter
1 1 ap
2 2 ap
3 -3 ap
4 4 ap
5 -5 ap
6 1 ef
7 2 ef
8 -3 ef
9 4 ef
10 -5 ef
11 1 tg
12 2 tg
13 -3 tg
14 4 tg
15 -5 tg
16 1 hk
17 2 hk
18 -3 hk
19 4 hk
20 -5 hk
21 1 bu
22 2 bu
23 -3 bu
24 4 bu
25 -5 bu
# 合併上面的數據
merge(bind_df_1, bind_df_3)
# 輸出結果
r$> merge(bind_df_1, bind_df_3)
[1] number
<0 列> (或零長度的 row.names
沒有留言:
張貼留言