在 r 中将两列堆叠为一列 (data.table)

stack two columns into one (data.table) in r

我有以下数据:

ID A B
1 4 2
2 5 3

我想要的结果是:

ID C
1 4
1 2
2 5
2 3

cdata 包具有转换函数,可以对多个变量进行透视和逆透视。我喜欢这个包的地方是控件 table 的想法,它以您想要查看的形式直观地排列数据。

在这种情况下,从数据帧开始df

ID <- c(1, 2)
A <- c(4, 5)
B <- c(2, 3)
df <- data.table(ID, A, B)


# check the data 
df[]

#>   ID A B
#> 1  1 4 2
#> 2  2 5 3

构建一个 cdata 控件 table。这是允许您明确分配哪些数据值去哪里的基本元素。在这种情况下,我使用一个新变量 from 来标识从中获取值的列,并且 C 是具有所需值的新列。

# build a control table
from <- c("col_A", "col_B")
C    <- c("A", "B")
control_table <- data.table(from, C)

# examine the result
control_table[]
#>     from C
#> 1: col_A A
#> 2: col_B B

准备好控件 table 后,我可以使用 cdata 中的 rowrecs_to_blocks() 将数据从行记录(宽)形式转换为块记录(较长)形式。 ID 变量根据需要重复多次以完成块记录。

# transform to block form
DT <- cdata::rowrecs_to_blocks(
  wideTable     = df, 
  controlTable  = control_table,
  columnsToCopy = c("ID"))
setDT(DT)

# examine the result
DT[]
#>    ID  from C
#> 1:  1 col_A 4
#> 2:  1 col_B 2
#> 3:  2 col_A 5
#> 4:  2 col_B 3

您可以省略 from 列,但保留它可以在需要时随时恢复原始数据帧。

# omit the from column
DT[, from := NULL]
DT
#>    ID C
#> 1:  1 4
#> 2:  1 2
#> 3:  2 5
#> 4:  2 3

使用 data.table,其中 meltdplyr 等价于 pivot_longer

dt <- data.table(ID = 1:2, A = 4:5, B = 2:3)

dt <- melt(dt, measure.vars = c("A", "B"), value.name = "C")
dt[, variable := NULL]
setorder(dt, ID) # to get the same order as your desired output

dt
#    ID C
# 1:  1 4
# 2:  1 2
# 3:  2 5
# 4:  2 3

只需使用by

DT[, .(C = c(A, B)), by = ID]
#       ID     C
#    <int> <int>
# 1:     1     4
# 2:     1     2
# 3:     2     5
# 4:     2     3

可重现的数据

DT = data.table(ID = 1:2, A = 4:5, B = 2:3)

我用这个命令来回答我的问题:

df1 %>% pivot_longer(cols = c(A,B),  values_to = "C") %>% 
        select(-name) 

感谢 Martin Gal 和 Gnueghoidune 之前的评论