如何解决绑定不同长度的数据帧无 cbind,无合并
我正在尝试将多个数据框并排显示以比较某些条目。但是,它们的行数不同,我希望每个数据框的顺序完全相同。
我尝试使用 cbind
由于行数不同而不起作用。我使用 merge
将两个 dfs 绑定在一起,然后再次合并它们,但是当我这样做时它们会改变顺序,并且当我总共有 5 个以上时合并两个 dfs 似乎效率低下。
示例:
df <- data.frame(v=1:5,x=sample(LETTERS[1:5],5))
df
v x
1 1 E
2 2 B
3 3 D
4 4 C
5 5 A
df2 <- data.frame(m=7:10,n=sample(LETTERS[6:9],4))
df2
m n
1 7 G
2 8 I
3 9 F
4 10 H
然后我订购了 df2
df2 <- df2[order(df2$m,decreasing = TRUE),]
df2
m n
4 10 F
3 9 I
2 8 H
1 7 G
预期输出:
v x m n
1 1 E 10 F
2 2 B 9 I
3 3 D 8 H
4 4 C 7 G
5 5 A NA NA
正如我所说,我有两个以上的dfs,dfs的顺序应该保持不变。任何帮助将不胜感激!
解决方法
编辑:如果有多个 df
。这样做
- 创建除第一个之外的所有 dfs 的列表
- 使用
purrr::reduce
将所有这些连接在一起 - 在
df
参数中传递第一个.init
。
df2 <- data.frame(m=7:10,n=sample(LETTERS[6:9],4))
df <- data.frame(v=1:5,x=sample(LETTERS[1:5],5))
df3 <- data.frame(bb = 101:110,cc = sample(letters,10))
reduce(list(df2,df3),.init = df %>% mutate(id = row_number()),~full_join(.x,.y %>% mutate(id = row_number()),by = "id" )) %>%
select(-id)
v x m n bb cc
1 1 A 10 I 101 u
2 2 C 9 H 102 v
3 3 D 8 G 103 n
4 4 E 7 F 104 w
5 5 B NA <NA> 105 s
6 NA <NA> NA <NA> 106 y
7 NA <NA> NA <NA> 107 g
8 NA <NA> NA <NA> 108 i
9 NA <NA> NA <NA> 109 p
10 NA <NA> NA <NA> 110 h
较早的答案:在两个 id
中创建一个虚拟列 df
并使用 full_join
full_join(df %>% mutate(id = row_number()),df2 %>% mutate(id = row_number()),by = "id") %>%
select(-id)
v x m n
1 1 A 10 I
2 2 C 9 H
3 3 D 8 G
4 4 E 7 F
5 5 B NA <NA>
由于随机数种子不同,结果与预期不同
或者在 BaseR 中
merge(transform(df,id = seq_len(nrow(df))),transform(df2,id = seq_len(nrow(df2))),all = T)
id v x m n
1 1 1 A 10 I
2 2 2 C 9 H
3 3 3 D 8 G
4 4 4 E 7 F
5 5 5 B NA <NA>
简单地通过子集[]删除额外的列
merge(transform(df,all = T)[-1]
v x m n
1 1 A 10 I
2 2 C 9 H
3 3 D 8 G
4 4 E 7 F
5 5 B NA <NA>
,
基础 R 方法:
将数据框放入列表中,获取行数最大的数据框,将 NA
附加到行数较少的数据和 cbind
。
list_df <- list(df,df2)
n_r <- seq_len(max(sapply(list_df,nrow)))
result <- do.call(cbind,lapply(list_df,`[`,n_r,))
result
# v x m n
#1 1 C 10 F
#2 2 B 9 H
#3 3 E 8 G
#4 4 D 7 I
#5 5 A NA <NA>
,
library(plyr)
combined <- rbind.fill(df[c("v","x")],df2[c("m","n")])
这是你想要的吗?
,另一种基本的 R 方法,但对于合并,您需要:
- 添加
sort
参数以确保结果不会被排序 - 从数据框中删除行名称
- 添加
all
参数以确保使用所有行, -
[-1]
是去掉merge添加的行名列
示例:
set.seed(123)
df1 <- data.frame(v = 1:5,x = sample(LETTERS[1:5],5))
df1
#> v x
#> 1 1 A
#> 2 2 B
#> 3 3 D
#> 4 4 C
#> 5 5 E
df2 <- data.frame(m = 7:10,n = sample(LETTERS[6:9],4))
df2
#> m n
#> 1 7 G
#> 2 8 H
#> 3 9 I
#> 4 10 F
df2 <- df2[order(df2$m,decreasing = TRUE),]
df2
#> m n
#> 4 10 F
#> 3 9 I
#> 2 8 H
#> 1 7 G
merge(data.frame(df1,row.names = NULL),data.frame(df2,by = 0,all = TRUE,sort = FALSE)[-1]
#> v x m n
#> 1 1 A 10 F
#> 2 2 B 9 I
#> 3 3 D 8 H
#> 4 4 C 7 G
#> 5 5 E NA <NA>
如果您需要超过 2 个数据帧,您可以使用 Reduce
。
df3 <- data.frame(a = 1:7,z = sample(LETTERS[1:7],7))
Reduce(function(x,y) merge(x = x,y = y,sort = FALSE)[-1],list(data.frame(df1,data.frame(df3,row.names = NULL)))
#> v x m n a z
#> 1 1 C 10 I 1 F
#> 2 2 B 9 F 2 G
#> 3 3 E 8 H 3 A
#> 4 4 D 7 G 4 B
#> 5 5 A NA <NA> 5 C
#> 6 NA <NA> NA <NA> 6 D
#> 7 NA <NA> NA <NA> 7 E
Created on 2021-04-22 by the reprex package (v2.0.0)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。