R语言:重复测量数据两次reshape失败求助
解决宽格式到长格式的数据重塑问题
我明白你现在卡在数据重塑这一步了——把包含6个Offer区块(每个区块10次重复测量)的宽格式数据转成包含DV、Timepoint和Offersize的长格式对吧?咱们一步步来解决这个问题。
问题分析
你之前尝试了两次reshape操作但没成功,大概率是这两个原因:
- 第一次
reshape用了固定列索引(比如32:41),如果原始数据的列顺序有变动就会出错; - 第二次
reshape的times参数用了1:6,但实际你需要的Offersize是0-5(对应Cero到Five),参数不匹配导致结果不符合预期。
下面我给你两种解决方案,分别用tidyverse(推荐,语法更直观)和base R来实现。
方案1:用tidyverse的pivot_longer(推荐)
pivot_longer可以直接拆分复杂的列名,一步到位完成重塑,代码可读性更高。
步骤1:加载包
library(tidyverse)
步骤2:处理数据(以你的示例数据为例)
你的示例数据包含CeroCent和FiveCent两个区块,实际如果是6个区块,只需要补充其他前缀即可:
example_processed <- example %>% # 把所有以CeroCent/OneCent/.../FiveCent开头的列转成长格式 pivot_longer( cols = starts_with(c("CeroCent", "OneCent", "TwoCent", "ThreeCent", "FourCent", "FiveCent")), # 拆分列名:前缀(比如CeroCent)和时间点(比如1) names_to = c("OfferPrefix", "Timepoint"), names_pattern = "(.*)\\.(\\d+)", # 把列值存入DV列 values_to = "DV" ) %>% # 把Offer前缀转换成对应的Offersize数字 mutate( Offersize = case_when( OfferPrefix == "CeroCent" ~ 0, OfferPrefix == "OneCent" ~ 1, OfferPrefix == "TwoCent" ~ 2, OfferPrefix == "ThreeCent" ~ 3, OfferPrefix == "FourCent" ~ 4, OfferPrefix == "FiveCent" ~ 5 ), # 确保Timepoint是整数类型 Timepoint = as.integer(Timepoint) ) %>% # 调整列顺序到你想要的目标格式 select(Sub, IV1, IV2, DV, Timepoint, Offersize) %>% # 按被试、区块、时间点排序,方便查看 arrange(Sub, Offersize, Timepoint)
处理后的数据样例
运行后你会得到类似这样的结果:
# A tibble: 50 × 6 Sub IV1 IV2 DV Timepoint Offersize <int> <int> <int> <int> <int> <dbl> 1 1 3 5 1 1 0 2 1 3 5 3 2 0 3 1 3 5 5 3 0 4 1 3 5 2 4 0 5 1 3 5 4 5 0 6 1 3 5 5 1 5 7 1 3 5 2 2 5 8 1 3 5 1 3 5 9 1 3 5 4 4 5 10 1 3 5 3 5 5 # ℹ 40 more rows
方案2:用base R的reshape
如果习惯用base R,也可以调整参数完成两次重塑:
步骤1:第一次重塑——拆分时间点
# 用grep匹配列名,比固定索引更可靠 dl <- reshape(example, varying = list( grep("CeroCent", names(example)), grep("OneCent", names(example)), grep("TwoCent", names(example)), grep("ThreeCent", names(example)), grep("FourCent", names(example)), grep("FiveCent", names(example)) ), v.names = c("CeroCent", "OneCent", "TwoCent", "ThreeCent", "FourCent", "FiveCent"), direction = "long", times = 1:10, # 你的原始数据是10次重复,示例数据是5次,按需修改 timevar = "Timepoint")
步骤2:第二次重塑——拆分区块(Offersize)
这里注意times参数要对应0-5,而不是1-6:
dl2 <- reshape(dl, varying = c("CeroCent", "OneCent", "TwoCent", "ThreeCent", "FourCent", "FiveCent"), v.names = "DV", direction = "long", times = c(0,1,2,3,4,5), # 对应每个区块的数字 timevar = "Offersize") # 清理多余列并调整顺序 dl2_final <- dl2 %>% select(Sub, IV1, IV2, DV, Timepoint, Offersize) %>% arrange(Sub, Offersize, Timepoint)
关键注意点
- 列名匹配:尽量用
grep或starts_with按列名匹配,避免用固定索引,防止列顺序变动导致错误; - 区块映射:
Cero对应0,Five对应5,这个映射关系一定要准确,否则Offersize列会出错; - 数据类型:确保
Timepoint和Offersize是整数类型,方便后续统计分析。
内容的提问来源于stack exchange,提问作者Martin Weiß
相关产品推荐
相关产品推荐

