数据框转换求助:如何用gather/spread实现模型对比所需格式?
解决R语言data.frame转换问题
我明白你想要把现有的长格式数据转换成以方法为行、变量为列的格式,还要保留每个方法对应的两组观测值。用tidyverse工具链就能轻松搞定,步骤如下:
首先加载需要的包:
library(tidyverse)
第一步,给原数据添加一个分组标识,用来区分每组A/B/C的两次观测(前3行是第一组,后3行是第二组):
df_with_group <- df %>% mutate(group = rep(1:2, each = 3))
接下来用gather把所有方法列(optimal、control、method_1、method_2)转成键值对格式,让每一行对应一个方法、一个变量和它的值:
gathered_df <- df_with_group %>% gather(key = "method", value = "value", -variable, -group)
然后用spread把变量(A/B/C)转成列,这样每个方法+分组就对应一行,包含A/B/C三个变量的值:
final_df <- gathered_df %>% spread(key = variable, value = value) %>% arrange(method, group) %>% # 按方法和分组排序,让相同方法的行挨在一起 select(-group) # 去掉分组列,得到目标格式
运行完这些代码后,final_df就是你想要的结构:
method A B C 1 optimal 10 20 30 2 optimal 40 80 100 3 control 15 15 15 4 control 15 15 15 5 method_1 11 22 28 6 method_1 44 85 95 7 method_2 9 19 31 8 method_2 39 79 102
这里的关键是添加分组列——原数据中每个变量(A/B/C)有两次观测,必须用分组来区分这两次记录,否则spread时会把相同方法的观测合并成一行,这也是你之前尝试没成功的核心原因。
如果你习惯用基础R,也可以用reshape包实现,代码如下:
# 基础R实现方式 library(reshape2) df$group <- rep(1:2, each = 3) melted <- melt(df, id.vars = c("variable", "group"), variable.name = "method") final_df_base <- dcast(melted, method + group ~ variable) final_df_base <- final_df_base[order(final_df_base$method, final_df_base$group), ] final_df_base <- final_df_base[, -2]
结果和tidyverse方法完全一致。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

