4列的部分聚集形成2列dplyr
这是一个玩具数据框4列的部分聚集形成2列dplyr,r,dplyr,R,Dplyr,这是一个玩具数据框 >library(tidyverse) >a id e0 e1 e2 ee 1 0 1 2 3 1 0 1 2 3 1 0 1 2 3 2 6 7 8 9 2 6 7 8 9 2 6 7 8 9 我想将前三列分组为开始,最后三列分组为结束,这样我可以得到以下结果 id start end 1 0 1 1 1
>library(tidyverse)
>a
id e0 e1 e2 ee
1 0 1 2 3
1 0 1 2 3
1 0 1 2 3
2 6 7 8 9
2 6 7 8 9
2 6 7 8 9
我想将前三列分组为开始,最后三列分组为结束,这样我可以得到以下结果
id start end
1 0 1
1 1 2
1 2 3
2 6 7
2 7 8
2 8 9
以R为基数:
do.call("rbind.data.frame",
list(
setNames(a2[,c("id","e0","e1")], c("id", "start", "end")),
setNames(a2[,c("id","e1","e2")], c("id", "start", "end")),
setNames(a2[,c("id","e2","ee")], c("id", "start", "end"))
))
编辑:根据注释,如果可以安全地假设每个id的行数正好等于e列数减去1,则可以执行以下操作:
nc <- 3
a %>%
group_by(id) %>%
mutate(
n = (row_number() - 1) %% nc + 1,
start = recode(n, e0, e1, e2),
end = recode(n, e1, e2, ee)
) %>%
ungroup() %>%
select(id, start, end)
# # A tibble: 6 × 3
# id start end
# <int> <int> <int>
# 1 1 0 1
# 2 1 1 2
# 3 1 2 3
# 4 2 6 7
# 5 2 7 8
# 6 2 8 9
事实上,即使没有正确的行数,这也会起作用,尽管如果不这样做,结果可能不正确。基本R选项是
data.frame(ID = a$id, start = unique(c(t(a[2:4]))), end = unique(c(t(a[3:5]))))
# ID start end
#1 1 0 1
#2 1 1 2
#3 1 2 3
#4 2 6 7
#5 2 7 8
#6 2 8 9
您的意思是,对于每个唯一的行,前三个是冗余的,例如,从e0到e1,然后从e1到e2,然后从e2到e3,并对每个不同的行执行此操作?是的,同时保持相同的id号。数据帧的长度不应增加。我原本想做一个mutatestart=gatherea,var,val,2:4和另一个mutateend=gatherea,var2,val2,3:5,但失败了。你是在寻找一个更通用的解决方案,可以跨越任意数量的列吗?你提供的非常完美!谢谢。你所做的编辑甚至没有必要。你的排练很棒!
nc <- 3
a %>%
group_by(id) %>%
mutate(
n = (row_number() - 1) %% nc + 1,
start = recode(n, e0, e1, e2),
end = recode(n, e1, e2, ee)
) %>%
ungroup() %>%
select(id, start, end)
# # A tibble: 6 × 3
# id start end
# <int> <int> <int>
# 1 1 0 1
# 2 1 1 2
# 3 1 2 3
# 4 2 6 7
# 5 2 7 8
# 6 2 8 9
data.frame(ID = a$id, start = unique(c(t(a[2:4]))), end = unique(c(t(a[3:5]))))
# ID start end
#1 1 0 1
#2 1 1 2
#3 1 2 3
#4 2 6 7
#5 2 7 8
#6 2 8 9