R:从具有匹配ID的长行转换为宽行和聚合行

时间:2016-03-09 20:59:48

标签: r dataframe transformation transpose reshape2

这是我一直在努力制作单独的数据框并执行full_join但我认为有一种更简单的方法。

总的来说,我想从长格式数据框中按类型计算从时间1到时间2的单个ID值之间的差异。这是我认为我可以做到的方式之一,但如果其他人有其他技巧或想法,我也希望听到它们。

但是,我也想知道如何解决这个转置问题,因为我很好奇。

这是我的问题。

我有一个长形式的数据框,在两个不同的时间段内有5种不同的度量。我想将这个数据框从长形式转换为宽形式,这样就不会像这样看DF(注意,并不是所有的类型都包括在内 - 为了长度而只做了2个):

(例子df1)

ID   Time  Value  Type
1     1      7     Type1
1     2      8     Type1
2     1      9     Type1
2     2      10    Type1
1     1      13    Type2
1     2      15    Type2
2     1      17    Type2
2     2      19    Type2

我希望它看起来更像这样:

(例如df 2)

ID   Type1.1   Type1.2    Type2.1  Type2.2
1      7          8          13      15
2      9          10         17      19 

我用:

library(dplyr)
library(tidyr)
df.new <- df %>%
spread(Type, Measurement.Value)

从示例df 1得到这个,这是在正确的轨道上:

(例如df 3)

ID    Time    Type1    Type2
1       1       7        13
1       2       8        15
2       1       9        17
2       2       10       19

但现在我想为每种类型分散时间。当我在示例df3上执行类似的操作时:

newer.df <- df.new %>%
spread(Time, Type1)

要做到这一点:

ID   Type1.1   Type1.2
1      7          NA 
1      NA         8 
2      9          NA
2      NA         10

所以,它为每一行产生一个NA - 有没有办法可以通过ID折叠彼此的行?我想我错过了什么。

请记住,在我的示例代码中,我只使用了2种类型,但实际上我有5种类型 - 只是想提供简化的代码。

2 个答案:

答案 0 :(得分:2)

我们可以使用dcast()包中的reshape2

library(reshape2)
dcast(df, ID ~ Type + Time, value.var = "Value")
#  ID Type1_1 Type1_2 Type2_1 Type2_2
#1  1       7       8      13      15
#2  2       9      10      17      19

答案 1 :(得分:1)

或者使用原始tidyr包,我们可以这样做:

library(tidyr)
df$Type <- paste(df$Type, df$Time, sep="_")
df$Time <- NULL
spread(df, key=Type, value=Value)
 ID Type1_1 Type1_2 Type2_1 Type2_2
  1       7       8      13      15
  2       9      10      17      19

取消时间栏对我来说是个窍门。似乎spread认为所有列都没有使用,否则dcast会调用id.vars。但是,使用tidyr可能会有更优雅的解决方案。