在 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
,其中 melt
是 dplyr
等价于 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 之前的评论
我有以下数据:
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
,其中 melt
是 dplyr
等价于 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 之前的评论