[英]Reshaping R dataframe (compute average of a column based on multiple 'level' columns)
我有一个具有这种类型的结构的R数据框(虚拟示例):
df
A B C D
1 a 3 5
1 a 5 3
1 b 2 8
2 a 4 7
2 a 6 5
2 b 4 3
...
“ A”,“ B”,“ C”和“ D”是列标题。
我想重塑此数据框,以便按“ A”和“ B”的每个级别获得“ C”和“ D”的平均值。
因此,我想要的最终产品将是:
new_df
A BaC BbC BaD BbD
1 4 2 4 8
2 5 4 6 3
我设法以一种非常粗糙的方式做到这一点:
spread_df_C <- spread(df, B, C)
aggregated_df_C <- aggregate(spread_df$a, list(spread_df$A), mean)
spread_df_D <- spread(df, B, D)
aggregated_df_D <- aggregate(spread_df$a, list(spread_df$A), mean)
new_df <- merge(aggregated_df_C, aggregated_df_D, by=c("A", "A")
这最终将使我获得最终产品,但是我正在努力计算每个级别的均值。 我需要在多个级别上执行此操作,并且必须有一种更优雅的执行方法。
专家请帮忙
使用reshape2
软件包的选项。
library(reshape2)
dcast(melt(dat, measure.vars = c("C", "D")), A ~ B + variable, fun.aggregate = mean)
# A a_C a_D b_C b_D
#1 1 4 4 2 8
#2 2 5 6 4 3
第一步是melt
列C
和D
,然后将结果数据帧转换回宽格式。
考虑聚合之后的基数R的reshape
以及句点之前/之后的列名切换:
agg <- aggregate(. ~ A + B, df, mean)
rdf <- reshape(agg, idvar = "A", timevar = "B", direction = "wide")
names(rdf)[-1] <- paste0("B", substr(names(rdf)[-1], 3, 3), substr(names(rdf)[-1], 1, 1))
rdf
# A BaC BaD BbC BbD
# 1 1 4 4 2 8
# 2 2 5 6 4 3
使用tidyverse
,您可以执行以下操作:
df %>%
gather(var, val, -c(1:2)) %>%
group_by_at(1:3) %>%
summarise(val = mean(val)) %>%
ungroup() %>%
mutate(var = paste(var, B, sep = "_")) %>%
select(-2) %>%
spread(var, val)
A C_a C_b D_a D_b
<int> <dbl> <dbl> <dbl> <dbl>
1 1 4 2 4 8
2 2 5 4 6 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.