在R中按参与者合并行:多时间点数据集整合需求
多时间点用户数据合并为单行解决方案
问题分析
你的数据集里每个用户对应多行(每行对应一个时间点),每个answer_tX列仅在对应时间行有有效值,其余为空。合并核心是按用户分组后,提取各answer列的非空值。
首先修正原始数据构造(避免生成矩阵,转为数据框):
name <- c("Ang", "Ang", "Ang", "Bot", "Bot") timepoint <- c("part 1", "part 2", "part 3", "part 1", "part 2") q1 <- c("More likely", "", "", "More likely", "") q2 <- c("", "Less likely", "", "", "More likely") q3 <- c("", "", "Less likely", "", "") # 转为数据框而非矩阵 df <- data.frame(name, timepoint, answer_t1 = q1, answer_t2 = q2, answer_t3 = q3, stringsAsFactors = FALSE)
方法一:data.table 实现
library(data.table) setDT(df) # 按name分组,提取各answer列的非空值 df_cleaned <- df[, lapply(.SD, function(x) x[x != ""]), by = name, .SDcols = patterns("answer_")]
如果需要将无值的单元格替换为NA:
df_cleaned <- df[, lapply(.SD, function(x) { val <- x[x != ""] if (length(val) == 0) NA_character_ else val }), by = name, .SDcols = patterns("answer_")]
方法二:dplyr 实现
library(dplyr) df_cleaned <- df %>% group_by(name) %>% summarise(across(starts_with("answer_"), ~ .[. != ""]), .groups = "drop")
替换空值为NA的版本:
df_cleaned <- df %>% group_by(name) %>% summarise(across(starts_with("answer_"), ~ { val <- .[. != ""] if (length(val) == 0) NA_character_ else val }), .groups = "drop")
为什么之前的方法无效?
你用的df[,lapply(.SD, paste0, collapse=""), by=name]会把空字符串和有效值拼接,且原始代码用cbind生成的是矩阵而非数据框,lapply对矩阵的处理逻辑和数据框不同,这是导致失败的核心原因。先转为数据框是关键前提。
内容的提问来源于stack exchange,提问作者Katherine
相关产品推荐
相关产品推荐

