【发布时间】:2021-12-12 09:25:17
【问题描述】:
我有一个如下所示的数据集:
(可视化下面的数据集可能有助于您理解问题)
original <- data.frame(
ID = c(rep("John", 4), "Steve"),
A = as.integer(c(rep(3, 4), 1)),
b = c(2, 3, 4, 2, 2),
B = c(rep(4, 4), 2),
detail1 = c("Yes", "Sure", "No", "Yes", "Yes"),
detail2 = c(rep("Unique1", 4), "Unique2")
)
A、B 和 b 中的值都是整数。变量b 在这个数据集中是不完整的,它实际上有从1 到B 的值。
我需要添加一个新变量a 来完成这个数据集,完成的数据集将如下所示:
completed1 <- data.frame(
ID = c(rep("John", 12), rep("Steve", 2)),
a = c(rep(1, 4), rep(2, 4), rep(3, 4), rep(1, 2)),
A = c(rep(3, 12), rep(1, 2)),
b = c(rep(1:4, 3), 1, 2),
B = c(rep(4, 12), rep(2, 2)),
detail1 = c("Absence", "Yes", "Sure", "No", "Absence", "Yes", rep("Absence", 7), "Yes"),
detail2 = c(rep("Unique1", 12), rep("Unique2", 2))
)
a 中的值也是整数,a 的值从 1 到 A 的值。 请注意 b 嵌套在 a。
我认为以这种方式完成数据集最相关的函数是tidyr::complete()和tidyr::expand(),但它们只能完成现有变量中的值组合,不能添加新列(变量)。
我知道挑战在于有多个位置可以在 detail1 对应新添加的值 a 通过嵌套关系,例如完成的数据集也可以是这样的:
completed2 <- data.frame(
ID = c(rep("John", 12), rep("Steve", 2)),
a = c(rep(1, 4), rep(2, 4), rep(3, 4), rep(1, 2)),
A = c(rep(3, 12), rep(1, 2)),
b = c(rep(1:4, 3), 1, 2),
B = c(rep(4, 12), rep(2, 2)),
detail1 = c("Absence", "Yes", rep("Absence", 4), "Sure", "Absence", "Absence", "Yes", "Absence", "No", "Absence", "Yes"),
detail2 = c(rep("Unique1", 12), rep("Unique2", 2))
)
我想按照上面completed1的逻辑完成数据集:detail1中的值先去a中的最小值,如果b中出现重复值(例如@ 987654343@ in b under John in original dataset),重复的值转到a中的下一个值。
可以这样做吗?
我的实际数据集比这个例子有更多的变量,完成的数据集将有超过 700,000 行,所以我更喜欢快速的方法来自动化它。
非常感谢!!!
【问题讨论】:
-
我认为添加
a是简单的部分,original %>% mutate(a = lapply(A, seq), b = lapply(B, seq)) %>% tidyr::unnest(a)应该可以做到。我可以想到几种方法来做b,但它们似乎不太好。我会睡在上面,看看有没有什么事情发生。 -
@GregorThomas 非常感谢!