Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用tidyr收集多个日期/值列_R_Reshape_Tidyr - Fatal编程技术网

使用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

我有一个数据集,其中包含多个列,其中包含重复测量的日期和相应值。有没有办法使用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 = 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