如何用dplyr在长格式数据中为参与者新增合成因子水平?
保持长格式添加合成因子的Tidyverse解决方案
完全理解你不想来回转宽转长的麻烦!我们可以直接在长格式数据上完成操作,通过分组计算合成因子,再把结果和原数据合并,全程不用改变数据的长格式结构。
具体步骤&代码
首先加载必要的包,并用你的示例数据来演示:
library(tidyverse) # 你的示例数据 df <- structure(list(first_name = c("P1", "P1", "P1", "P1", "P1", "P1", "P1", "P1", "P1", "P1", "P1", "P1"), subscales = structure(1:12, .Label = c("Emotion Regulation", "Empathy", "Family Support", "Gratitude", "Optimism", "Peer Support", "Persistence", "School Support", "Self-Awareness", "Self-Control", "Self-Efficacy", "Zest"), class = "factor"), value = c(5L, 7L, 10L, 12L, 12L, 9L, 5L, 8L, 7L, 6L, 8L, 12L)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -12L))
接下来,我们按参与者分组,计算两个合成因子的总和,生成新的行后直接合并到原数据:
# 先定义合成因子与对应子量表的映射关系 composite_factors <- list( "Engaged Living" = c("Optimism", "Zest", "Gratitude"), "Emotional Competence" = c("Emotion Regulation", "Self-Control", "Empathy") ) # 生成合成因子行并合并到原数据 df_with_composites <- df %>% group_by(first_name) %>% summarize( # 为每个合成因子创建对应的行 subscales = names(composite_factors), value = map_int(composite_factors, ~sum(value[subscales %in% .x])), .groups = "drop" ) %>% # 把新生成的合成因子行追加到原数据后面 bind_rows(df) %>% # 可选操作:整理因子水平顺序,让合成因子排在前面(也可以按你需要调整) mutate(subscales = fct_inorder(subscales))
代码逻辑解释
group_by(first_name):确保我们是按每个参与者单独计算合成因子,不会把不同参与者的数据混在一起summarize里的map_int:遍历我们定义的合成因子列表,对每个参与者筛选出对应子量表的数值并求和,自动生成新的subscales和value配对bind_rows(df):直接把新的合成因子行追加到原数据末尾,全程保持长格式fct_inorder:可选步骤,让因子水平按数据中的出现顺序排列,避免合成因子默认跑到现有因子的最后
输出结果预览
运行后,你会看到每个参与者(比如示例里的P1)的行中新增了两行:
# A tibble: 14 x 3 first_name subscales value <chr> <fct> <int> 1 P1 Engaged Living 36 2 P1 Emotional Competence 18 3 P1 Emotion Regulation 5 4 P1 Empathy 7 ...
这种方法全程不用转换数据格式,完全贴合tidyverse的工作流,高效又简洁!
内容的提问来源于stack exchange,提问作者Pss
相关产品推荐
相关产品推荐

