将两个数据表合并为一个,R 中交替使用列



我有两个数据表,odd_dataeven_data。我想将它们合并/合并为一个,all_data其中all_data的奇数列是odd_data列,偶数列是even_data列。但是,我尝试的会抛出错误。

假设odd_dataeven_data如下所示:

odd_data
   col_1 col_3
    11    13
    21    23
    31    33
even_data
  col_2 col_4
    12    14
    22    24
    32    34

所需结果如下所示:

all_data
   col_1 col_2 col_3 col_4
    11    12    13    14
    21    22    23    24
    31    32    33    34

我尝试了以下几种:

odd_data = data.table(col_1 = c(11, 21, 31),
                      col_3 = c(13, 23, 33))

even_data = data.table(col_2 = c(12, 22, 32),
                       col_4 = c(14, 24, 34))
all_data <- data.table(matrix(nrow = nrow(odd_data), ncol = (ncol(odd_data)*2)))
# change the name of columns of all_data to match column names of odd/even_data
colnames_data <- colnames(all_data)
setnames(all_data, old=colnames_data[c(TRUE, FALSE)], new= colnames(odd_data))
setnames(all_data, old=colnames_data[c(FALSE, TRUE)], new= colnames(even_data))
all_data[, c(rep(c(TRUE, FALSE), 2))] <- odd_data

错误是

Error in `[<-.data.table`(`*tmp*`, , c(rep(c(TRUE, FALSE), 2)), value = list( : 
  j must be vector of column name or positions
您可以

直接cbind它们,然后对列重新排序:

neworder <- order(c(2*(seq_along(odd_data) - 1) + 1,
                    2*seq_along(even_data)))
cbind(odd_data, even_data)[,neworder]
#    col_1 col_2 col_3 col_4
# 1:    11    12    13    14
# 2:    21    22    23    24
# 3:    31    32    33    34

解释:

### count by odds
2*(seq_along(odd_data) - 1) + 1
# [1] 1 3
### count by evens
2*seq_along(even_data)
# [1] 2 4
neworder
# [1] 1 3 2 4

这给了我们最终想要的列顺序:第一列(col_1(,第三列(col_2,因为它在第一个表的所有列之后(等。

为了进行测试,我们可以生成两个非对称示例:

odd_data = data.table(col_1 = c(11, 21, 31),
                      col_3 = c(13, 23, 33),
                      col_5 = c(15, 25, 35))
even_data = data.table(col_2 = c(12, 22, 32),
                       col_4 = c(14, 24, 34))
neworder <- order(c(2*(seq_along(odd_data) - 1) + 1,
                    2*seq_along(even_data)))
cbind(odd_data, even_data)[,neworder]
#    col_1 col_2 col_3 col_4 col_5
# 1:    11    12    13    14    15
# 2:    21    22    23    24    25
# 3:    31    32    33    34    35

接下来,3 和 3:

odd_data = data.table(col_1 = c(11, 21, 31),
                      col_3 = c(13, 23, 33),
                      col_5 = c(15, 25, 35))
even_data = data.table(col_2 = c(12, 22, 32),
                       col_4 = c(14, 24, 34),
                       col_6 = c(16, 26, 36))
neworder <- order(c(2*(seq_along(odd_data) - 1) + 1,
                    2*seq_along(even_data)))
cbind(odd_data, even_data)[,neworder]
#    col_1 col_2 col_3 col_4 col_5 col_6
# 1:    11    12    13    14    15    16
# 2:    21    22    23    24    25    26
# 3:    31    32    33    34    35    36

现在,如果我们想尝试通过拥有比赔率更多的偶数来搞砸系统(这"不应该"发生(:

odd_data = data.table(col_1 = c(11, 21, 31),
                      col_3 = c(13, 23, 33),
                      col_5 = c(15, 25, 35))
even_data = data.table(col_2 = c(12, 22, 32),
                       col_4 = c(14, 24, 34),
                       col_6 = c(16, 26, 36),
                       col_8 = c(18, 28, 38))
neworder <- order(c(2*(seq_along(odd_data) - 1) + 1,
                    2*seq_along(even_data)))
cbind(odd_data, even_data)[,neworder]
#    col_1 col_2 col_3 col_4 col_5 col_6 col_8
# 1:    11    12    13    14    15    16    18
# 2:    21    22    23    24    25    26    28
# 3:    31    32    33    34    35    36    38

因此,虽然col_8在技术上不是第 8 列,但所有其他列的顺序仍然保留。

你可以像这样使用dplyr包中的bind_cols

bind_cols(odd_data,even_data)[,c(1,3,2,4)]

最新更新