微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

绑定不同长度的数据帧无 cbind,无合并

如何解决绑定不同长度的数据帧无 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 举报,一经查实,本站将立刻删除。