使用tidyr收集多个日期/值列
我有一个数据集,其中包含多个列,其中包含重复测量的日期和相应值。有没有办法使用tidyr将其转换为一个包含其他数据的长数据集,并且只包含两列(一列用于日期,一列用于值) 以下代码生成一个示例数据帧:使用tidyr收集多个日期/值列,r,reshape,tidyr,R,Reshape,Tidyr,我有一个数据集,其中包含多个列,其中包含重复测量的日期和相应值。有没有办法使用tidyr将其转换为一个包含其他数据的长数据集,并且只包含两列(一列用于日期,一列用于值) 以下代码生成一个示例数据帧: df <- data.frame( id = 1:10, age = sample(100, 10), date1 = as.Date('2015-09-22') - sample(100, 10), value1 = sample(100, 10), date2
df <- data.frame(
id = 1:10,
age = sample(100, 10),
date1 = as.Date('2015-09-22') - sample(100, 10),
value1 = sample(100, 10),
date2 = as.Date('2015-09-22') - sample(100, 10),
value2 = sample(100, 10),
date3 = as.Date('2015-09-22') - sample(100, 10),
value3 = sample(100, 10))
我最后想要的是:
id age date value
1 1 32 2015-08-01 37
2 1 32 2015-07-15 38
3 1 32 2015-09-09 81
4 2 33 2015-07-22 16
5 2 33 2015-06-26 1
...
30 10 64 2015-08-05 90
如果您能在tidyr或重塑中提供帮助,我们将不胜感激。应该有一些有效的方法,但这是一种方法 分别为日期和价值工作
#for date
df.date<-df%>%select(id, age,date1,date2, date3)%>%melt(id.var=c("id", "age"), value.name="date")
#for val
df.val<-df%>%select(id, age,value1,value2, value3)%>%melt(id.var=c("id", "age"), value.name="value")
现在加入
df2<-full_join(df.date, df.val, by=c("id", "age"))
df2%>%select(-variable.x, -variable.y)
id age date value
1 1 40 2015-07-19 28
2 1 40 2015-07-19 49
3 1 40 2015-07-19 24
4 2 33 2015-06-27 99
5 2 33 2015-06-27 18
6 2 33 2015-06-27 26
7 3 75 2015-07-07 63
8 3 75 2015-07-07 74
9 3 75 2015-07-07 72
相同的策略,但改用tidyr如下所示:
df.value <- df %>%
gather(key="foo", value="value", starts_with("value"))
df.date <- df %>%
gather(key="bar", value="date", starts_with("date"))
我确信这两个部分都有一种更为巧妙的方法,但它确实起到了作用。我在尝试学习如何混合使用日期和值的聚集时偶然发现了这一点 现有答案会丢失有关日期-值对来自哪个实例的信息,例如,date1和value1的实例1等。这可能不重要,但这里有一个保留实例的tidyverse选项
library(stringr) # not necessary but nice
library(tidyr)
library(dplyr)
df %>%
gather(key, val, -id, -age) %>%
mutate(
measure = str_sub(key,1,-2),
instance = str_sub(key, -1)
) %>%
select(-key) %>%
spread(measure, val) %>%
mutate(date = as.Date(date, origin="1970-01-01")) # restore date class
对于我正在处理的数据集,我有完全相同的问题和数据格式。在工作中众包寻找答案。我们中的一些人提出了一个tidyr和dplyr管道解决方案。使用与原始问题相同的模拟df
df %>%
gather(key = date_position, value = date, starts_with("date")) %>%
gather(key = value_position, value = value, starts_with("value")) %>%
mutate(date_position = gsub('[^0-9]', "", date_position),
value_position = gsub('[^0-9]', "", value_position)) %>%
filter(date_position == value_position) %>%
select(-ends_with("position")) %>%
arrange(id)
这将对行进行重塑,然后对行进行排序
前两行只是设置了v.names和要重塑的各种参数。v、 names定义了新的列名,Variable是一个列表,它的两个组件分别包含日期列和值列的逻辑选择向量
最后一行代码进行排序,如果行顺序无关紧要,则可以省略
没有使用任何软件包
v.names <- c("date", "value")
varying <- lapply(v.names, startsWith, x = names(df))
r <- reshape(df, dir = "long", varying = varying, v.names = v.names)
r[order(r$id, r$time), ]
我得出了相同的结论,分别使用tidyr收集了这两种类型的专栏-我发布了答案以供参考。我看到了几个非常相似的问题/答案,其中一个可能是完全重复的-请参阅和
df %>%
gather(key = date_position, value = date, starts_with("date")) %>%
gather(key = value_position, value = value, starts_with("value")) %>%
mutate(date_position = gsub('[^0-9]', "", date_position),
value_position = gsub('[^0-9]', "", value_position)) %>%
filter(date_position == value_position) %>%
select(-ends_with("position")) %>%
arrange(id)
v.names <- c("date", "value")
varying <- lapply(v.names, startsWith, x = names(df))
r <- reshape(df, dir = "long", varying = varying, v.names = v.names)
r[order(r$id, r$time), ]
id age time date value
1.1 1 12 1 2015-08-14 3
1.2 1 12 2 2015-07-11 24
1.3 1 12 3 2015-07-04 4
2.1 2 92 1 2015-08-03 17
2.2 2 92 2 2015-07-19 52
2.3 2 92 3 2015-07-01 93
3.1 3 28 1 2015-08-24 86
3.2 3 28 2 2015-08-12 80
3.3 3 28 3 2015-09-01 56
4.1 4 45 1 2015-09-13 78
4.2 4 45 2 2015-07-07 92
4.3 4 45 3 2015-08-10 81
5.1 5 25 1 2015-08-27 95
5.2 5 25 2 2015-09-08 68
5.3 5 25 3 2015-06-27 82
6.1 6 1 1 2015-08-21 16
6.2 6 1 2 2015-06-15 35
6.3 6 1 3 2015-07-24 30
7.1 7 7 1 2015-07-19 59
7.2 7 7 2 2015-07-08 33
7.3 7 7 3 2015-08-11 49
8.1 8 71 1 2015-07-28 19
8.2 8 71 2 2015-06-29 74
8.3 8 71 3 2015-08-05 25
9.1 9 59 1 2015-07-05 64
9.2 9 59 2 2015-09-04 30
9.3 9 59 3 2015-07-30 74
10.1 10 96 1 2015-09-12 69
10.2 10 96 2 2015-07-23 72
10.3 10 96 3 2015-08-19 23