Tho*_*s K 2 r reshape reshape2 data.table tidyr
这里已经解决了收集多组列的问题:收集多组列,但在我的情况下,列不是唯一的.
我有以下数据:
input <- data.frame(
id = 1:2,
question = c("a", "b"),
points = 0,
max_points = c(3, 5),
question = c("c", "d"),
points = c(0, 20),
max_points = c(5, 20),
check.names = F,
stringsAsFactors = F
)
input
#> id question points max_points question points max_points
#> 1 1 a 0 3 c 0 5
#> 2 2 b 0 5 d 20 20
Run Code Online (Sandbox Code Playgroud)
第一列是id,然后我有很多重复的列(原始数据集有133列):
我想结束这个结构:
expected <- data.frame(
id = c(1, 2, 1, 2),
question = letters[1:4],
points = c(0, 0, 0, 20),
max_points = c(3, 5, 5, 20),
stringsAsFactors = F
)
expected
#> id question points max_points
#> 1 1 a 0 3
#> 2 2 b 0 5
#> 3 1 c 0 5
#> 4 2 d 20 20
Run Code Online (Sandbox Code Playgroud)
我尝试了几件事:
tidyr::gather(input, key, val, -id)reshape2::melt(input, id.vars = "id")两者都无法提供所需的输出.此外,由于列数多于此处显示的列数,因此gather不再有效,因为副本列太多了.
作为一种解决方法,我试过这个:
# add numbers to make col headers "unique"
names(input) <- c("id", paste0(1:(length(names(input)) - 1), names(input)[-1]))
# gather, remove number, spread
input %>%
gather(key, val, -id) %>%
mutate(key = stringr::str_replace_all(key, "[:digit:]", "")) %>%
spread(key, val)
Run Code Online (Sandbox Code Playgroud)
这给出了一个错误: Duplicate identifiers for rows (3, 9), (4, 10), (1, 7), (2, 8)
这里已经讨论过这个问题:tidyr的意外行为,但我不知道为什么/如何添加另一个标识符.最有可能这不是主要问题,因为我可能应该以不同的方式处理整个问题.
我怎么能解决我的问题,最好tidyr还是基地?我不知道如何使用data.table,但如果有一个简单的解决方案,我也会满足于此.
试试这个:
do.call(rbind,
lapply(seq(2, ncol(input), 3), function(i){
input[, c(1, i:(i + 2))]
})
)
# id question points max_points
# 1 1 a 0 3
# 2 2 b 0 5
# 3 1 c 0 5
# 4 2 d 20 20
Run Code Online (Sandbox Code Playgroud)