R rbind 同时保留每个数据帧中的顺序或行
R rbind while preserving order or rows in each data frame
我需要合并 2 个数据框,同时保留它们在每个数据框中的出现顺序:
x = data.frame(a=1:3, b=2:4, c=3:5)
y = data.frame(a=c(10, 20, 30), b=c(20, 30, 40), c=c(30, 40, 50))
我想要的是:
> z
a b c
1 2 3
10 20 30
2 3 4
20 30 40
3 4 5
30 40 50
但是 rbind 所做的是在第一个数据帧下添加第二个数据帧。
您应该为每个数据框添加行号变量,并在绑定后按此变量排序。使用 dplyr
,您可以按以下方式执行此操作:
library(dplyr)
x %>%
mutate(rn = row_number()) %>%
bind_rows(
y %>%
mutate(rn = row_number())
) %>%
arrange(rn)%>%
select(-4)
您可以在基础 R
:
中使用 Paweł 的行号想法
x$rowid <- seq(1, nrow(x)*2, by = 2) # or simply 1:nrow(x)
y$rowid <- seq(2, nrow(y)*2, by = 2)
z <- rbind(x, y)
z[order(z$rowid),]
a b c rowid
1 1 2 3 1
4 10 20 30 2
2 2 3 4 3
5 20 30 40 4
3 3 4 5 5
6 30 40 50 6
edit 也可以使用 rbind() 生成的行名:
z <- do.call(rbind, list(x = x, x = y))
z[order(rownames(z)), ]
a b c
x.1 1 2 3
x.11 10 20 30
x.2 2 3 4
x.21 20 30 40
x.3 3 4 5
x.31 30 40 50
试试这个单线
do.call("rbind", Map("rbind", split(x, 1:nrow(x)), split(y, 1:nrow(y))))
如果 x
和 y
与问题中的一样,则给出此 data.frame:
a b c
1.1 1 2 3
1.2 10 20 30
2.2 2 3 4
2.21 20 30 40
3.3 3 4 5
3.31 30 40 50
它按行拆分每个数据帧,然后将拆分的相应组件绑定。然后它会绑定所有这些。请注意,即使列具有不同的类型,此单行代码也能正常工作。例如,它会工作,即使:
x <- data.frame(a = letters[1:3], b = 1:3, c = c(TRUE, FALSE, TRUE))
y <- data.frame(a = LETTERS[1:3], b = 11:13, c = c(FALSE, TRUE, FALSE))
作为另一个基础 r 版本:
x = data.frame(a=1:3, b=2:4, c=3:5)
y = data.frame(a=c(10, 20, 30), b=c(20, 30, 40), c=c(30, 40, 50))
mapply(FUN = function(i,j){rbind(i,j)}, x, y)
#> a b c
#> [1,] 1 2 3
#> [2,] 10 20 30
#> [3,] 2 3 4
#> [4,] 20 30 40
#> [5,] 3 4 5
#> [6,] 30 40 50
由 reprex package (v0.2.1)
创建于 2019-02-14
为了完整起见,还有一个data.table
解决方案。
library(data.table)
dt.x <- data.table(x)
dt.y <- data.table(y)
dt.x[,Row.Num :=seq(1:.N)]
dt.y[,Row.Num :=seq(1:.N)]
rbindlist(list(dt.x,dt.y), idcol = TRUE)[order(Row.Num),]
我需要合并 2 个数据框,同时保留它们在每个数据框中的出现顺序:
x = data.frame(a=1:3, b=2:4, c=3:5)
y = data.frame(a=c(10, 20, 30), b=c(20, 30, 40), c=c(30, 40, 50))
我想要的是:
> z
a b c
1 2 3
10 20 30
2 3 4
20 30 40
3 4 5
30 40 50
但是 rbind 所做的是在第一个数据帧下添加第二个数据帧。
您应该为每个数据框添加行号变量,并在绑定后按此变量排序。使用 dplyr
,您可以按以下方式执行此操作:
library(dplyr)
x %>%
mutate(rn = row_number()) %>%
bind_rows(
y %>%
mutate(rn = row_number())
) %>%
arrange(rn)%>%
select(-4)
您可以在基础 R
:
x$rowid <- seq(1, nrow(x)*2, by = 2) # or simply 1:nrow(x)
y$rowid <- seq(2, nrow(y)*2, by = 2)
z <- rbind(x, y)
z[order(z$rowid),]
a b c rowid
1 1 2 3 1
4 10 20 30 2
2 2 3 4 3
5 20 30 40 4
3 3 4 5 5
6 30 40 50 6
edit 也可以使用 rbind() 生成的行名:
z <- do.call(rbind, list(x = x, x = y))
z[order(rownames(z)), ]
a b c
x.1 1 2 3
x.11 10 20 30
x.2 2 3 4
x.21 20 30 40
x.3 3 4 5
x.31 30 40 50
试试这个单线
do.call("rbind", Map("rbind", split(x, 1:nrow(x)), split(y, 1:nrow(y))))
如果 x
和 y
与问题中的一样,则给出此 data.frame:
a b c
1.1 1 2 3
1.2 10 20 30
2.2 2 3 4
2.21 20 30 40
3.3 3 4 5
3.31 30 40 50
它按行拆分每个数据帧,然后将拆分的相应组件绑定。然后它会绑定所有这些。请注意,即使列具有不同的类型,此单行代码也能正常工作。例如,它会工作,即使:
x <- data.frame(a = letters[1:3], b = 1:3, c = c(TRUE, FALSE, TRUE))
y <- data.frame(a = LETTERS[1:3], b = 11:13, c = c(FALSE, TRUE, FALSE))
作为另一个基础 r 版本:
x = data.frame(a=1:3, b=2:4, c=3:5)
y = data.frame(a=c(10, 20, 30), b=c(20, 30, 40), c=c(30, 40, 50))
mapply(FUN = function(i,j){rbind(i,j)}, x, y)
#> a b c
#> [1,] 1 2 3
#> [2,] 10 20 30
#> [3,] 2 3 4
#> [4,] 20 30 40
#> [5,] 3 4 5
#> [6,] 30 40 50
由 reprex package (v0.2.1)
创建于 2019-02-14为了完整起见,还有一个data.table
解决方案。
library(data.table)
dt.x <- data.table(x)
dt.y <- data.table(y)
dt.x[,Row.Num :=seq(1:.N)]
dt.y[,Row.Num :=seq(1:.N)]
rbindlist(list(dt.x,dt.y), idcol = TRUE)[order(Row.Num),]