我有几千行这种形式的数据:
a= c("id", "start", "mid1", "mid2", "finish")
b= c("id1", "date1", "date2", "date3", "date4")
c= c("id2", "date5", "date6", NA, "date7")
d= c("id3", "date8", "date9", "date10", "date11")
df=as.data.frame(rbind(b,c,d))
colnames(df)=a
rownames(df)=c(1:nrow(df))
df
# id start mid1 mid2 finish
# 1 id1 date1 date2 date3 date4
# 2 id2 date5 date6 <NA> date7
# 3 id3 date8 date9 date10 date11
# ...
我需要以这种形式获得它:
id; event ;date
id1; start ;date1
id1; mid1 ;date2
id1; mid2 ;date3
id1; finish ;date4
id2; start ;date5
id2; mid1 ;date6
id2; finish ;date7
id3; start ;date8
id3; mid1 ;date9
id3; mid2 ;date10
id3; finish ;date11
...
我发现这个问题几乎相同但反之亦然:How to transform Columns to rows in R?
我怎样才能完成转型?
答案 0 :(得分:2)
如评论中所述,您可以使用tidyr::gather
。在这里,我将其与dplyr
结合使用,并将其与%>%
一起链接。
library(tidyr); library(dplyr)
df %>%
gather(event, date, -id) %>%
arrange(id) %>%
filter(!is.na(date))
导致
id event date
1 id1 start date1
2 id1 mid1 date2
3 id1 mid2 date3
4 id1 finish date4
5 id2 start date5
6 id2 mid1 date6
7 id2 finish date7
8 id3 start date8
9 id3 mid1 date9
10 id3 mid2 date10
11 id3 finish date11
答案 1 :(得分:1)
您需要在原始数据中添加NA
而不是空白,并且正如Davide使用melt
所述,忽略NA
以获得您想要的结果:
> df
id start mid1 mid2 finish
1 id1 date1 date2 date3 date4
2 id2 date5 date6 <NA> date7
3 id3 date8 date9 date10 date11
library(reshape2)
melt(df, id.vars="id", variable.name="event",value.name="date",na.rm=TRUE)
答案 2 :(得分:1)
出于各种原因,您可以在基础R中执行以下操作:
cbind(df[1], stack(lapply(df[-1], as.character)), row.names = NULL)
# id values ind
# 1 id1 date1 start
# 2 id2 date5 start
# 3 id3 date8 start
# 4 id1 date2 mid1
# 5 id2 date6 mid1
# 6 id3 date9 mid1
# 7 id1 date3 mid2
# 8 id2 <NA> mid2
# 9 id3 date10 mid2
# 10 id1 date4 finish
# 11 id2 date7 finish
# 12 id3 date11 finish
如果您想要删除na.omit
并使用NA
以所需的行顺序获取数据,则可以将其包装在order
中。