R:从长转宽并聚合具有匹配 ID 的行
R: Transposing from long to wide and aggregating rows with matching ID
这是我已经研究了一段时间的东西,只是制作单独的数据框并做 full_join,但我认为有更简单的方法。
总的来说,我想从长格式数据框中按类型计算个人 ID 从时间 1 到时间 2 的值之间的差异。这是我认为我可以做到的方法之一,但如果其他人有其他技术或想法,我也想听听他们的意见。
但是,我也想知道如何解决这个移调问题,因为我很好奇。
这是我的问题。
我有一个长格式的数据框,其中包含针对两个不同时间段的 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 种类型——只是想提供简化的代码。
我们可以使用 reshape2
包中的 dcast()
。
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
或者使用原始的 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
可能会有更优雅的解决方案。
这是我已经研究了一段时间的东西,只是制作单独的数据框并做 full_join,但我认为有更简单的方法。
总的来说,我想从长格式数据框中按类型计算个人 ID 从时间 1 到时间 2 的值之间的差异。这是我认为我可以做到的方法之一,但如果其他人有其他技术或想法,我也想听听他们的意见。
但是,我也想知道如何解决这个移调问题,因为我很好奇。
这是我的问题。
我有一个长格式的数据框,其中包含针对两个不同时间段的 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 种类型——只是想提供简化的代码。
我们可以使用 reshape2
包中的 dcast()
。
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
或者使用原始的 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
可能会有更优雅的解决方案。