这是我一直在努力制作单独的数据框并执行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种类型 - 只是想提供简化的代码。
答案 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
可能会有更优雅的解决方案。