【发布时间】:2021-01-25 03:58:41
【问题描述】:
我正在尝试在 R 中将 data.table 从宽变为长。我需要减少几组变量,但我最初一次做一组的方法看起来很容易出错,我'想要一个替代方案。在这个可重现的示例中,我以与原始数据类似的方式创建了两组变量(XX 和 YYY)。
我的解决方案在此示例中有效,但原始数据表包含太多列,以至于我对信任此代码感到不安。我不确定问题出在我的实现还是方法本身 - 如果可能,我更喜欢keep it simple。
问:有没有更好的方法来解决这个问题?
示例数据
library(data.table)
dt.orig <- data.table(ID= 1:3,
a = c("Y", "Y", "N"),
b = c("N", "Y", "Y"),
XXa=c(101, 102, 103),
XXb=c(110, 120, 130),
YYYa=c(201, 202, 203),
YYYb=c(210, 220, 230))
dt.goal <- data.table(ID=c(1,1,2,2,3,3),
obs=c("a", "b"),
outcome = c("Y", "N", "Y", "Y", "N", "Y"),
XX=c(101, 110, 102, 120, 103, 130),
YYY=c(201, 210, 202, 220, 203, 230))
> dt.orig
ID a b XXa XXb YYYa YYYb
1: 1 Y N 101 110 201 210
2: 2 Y Y 102 120 202 220
3: 3 N Y 103 130 203 230
> dt.goal
ID obs outcome XX YYY
1: 1 a Y 101 201
2: 1 b N 110 210
3: 2 a Y 102 202
4: 2 b Y 120 220
5: 3 a N 103 203
6: 3 b Y 130 230
dt.orig代表原始数据,dt.goal是我打算实现的。我在tidyr 包小插图之后的初步尝试如下:
尝试 1:tidyr/dplyr 方法
library(tidyr)
library(dplyr)
dt.orig[, .(ID, a, b)] %>%
pivot_longer(
cols = c("a", "b"),
names_to = "obs",
values_to = "outcome"
) %>% data.table -> dt.tidyr1
dt.orig[, .(ID, XXa, XXb, YYYa, YYYb)] %>%
pivot_longer(
cols = XXa:YYYb,
names_to = c(".value", "obs"),
names_pattern = "(XX|YYY)(.)",
) %>% data.table -> dt.tidyr2
dt.tidyr1[, .(ID, obs, outcome)] == dt.goal[, .(ID, obs, outcome)] # test passes
dt.tidyr2[, .(ID, obs, XX, YYY)] == dt.goal[, .(ID, obs, XX, YYY)] # test passes
> merge(dt.tidyr1, dt.tidyr2)
ID obs outcome XX YYY
1: 1 a Y 101 201
2: 1 b N 110 210
3: 2 a Y 102 202
4: 2 b Y 120 220
5: 3 a N 103 203
6: 3 b Y 130 230
在上面的代码中,我首先为obs 和a 和b 的结果创建了一对名称/值。由于所有变量组在其命名方案中都包含a 和b,因此我可以使用这一事实通过单个regex 传递所有组。
然后我可以将两个数据表合并或连接到最终结果中。
尝试 2:data.table 方式
按照相同的原则,我可以开始将原始 a 和 b 融合为 obs 和结果,然后针对每个 var 组进行第二步(为简洁起见,此处未显示)。在这种情况下,我一次成功地融合了一个 var 组,因此在此示例中,首先执行所有 XX,然后执行所有 YYY。优点/缺点:优点是我不需要创建几个步骤表来完成这个过程。缺点:世界上没有足够的咖啡来使用实际数据中的所有 var 组来完成这种方法(并相信结果)。
dt.melt1 <- melt(dt.orig,
id.vars = c("ID", "XXa", "XXb", "YYYa", "YYYb"),
measure = c("a", "b"),
variable.name = "obs",
value.name = "outcome")
【问题讨论】:
标签: r data.table reshape tidyr