R使用pivot_wider转换宽表去重及数值异常问题解决
R pivot_wider长表转宽表重复报错解决方案
问题根因
你遇到的警告本质是pivot_wider指定的id_cols字段组合,无法在全量数据中唯一标识每一行,同一个id_cols+label的组合对应了多个responses值,导致工具无法确定要保留哪一个值。你看到的随机数字,实际是默认把多值转成列表后,输出的列表对象内存地址/长度值,不是真正的回答内容。
代码修改方案
第一步:先定位重复行
运行以下代码找出所有重复的组合,确认重复产生的逻辑:
library(dplyr) # 统计每个id+label组合的出现次数,n>1即为重复 gwlsubset %>% count(ID, full_name, date_of_birth, encounterID, practice_name, practice_id, label) %>% filter(n > 1)
第二步:去重后转换
如果是完全重复的行,直接先去重再转换即可:
library(tidyr) library(dplyr) subset <- gwlsubset %>% # 按所有字段去重,删除完全一致的冗余行 distinct() %>% pivot_wider( id_cols = c(ID, full_name, date_of_birth, encounterID, practice_name, practice_id), names_from = label, # 注意原数据回答列名是responses,不要漏写末尾的s values_from = responses )
如果同一个组合下存在多个有效回答,需要自定义聚合规则,比如取第一个非空值:
subset <- gwlsubset %>% distinct() %>% pivot_wider( id_cols = c(ID, full_name, date_of_birth, encounterID, practice_name, practice_id), names_from = label, values_from = responses, # 多值时取第一个非空回答 values_fn = function(x) first(na.omit(x)) )
如果需要保留所有回答,可拼接为字符串:
values_fn = function(x) paste(unique(x), collapse = "; ")
其他可能引发异常的原因
- 字段名匹配错误:你示例代码中
values_from写的是response,但原数据集的回答列名是responses,少写了末尾的s。如果全量数据中存在名为response的数值列,就会读取错误的数值,导致输出结果为数字。 id_cols选择不全:全量数据中存在同一个用户同一次就诊多次填写问卷的情况,现有id_cols没有区分多次提交的字段(比如提交时间、问卷版本号),导致重复。可在id_cols中补充对应的标识字段解决。- 隐形字符/数据类型不一致:比如ID、日期字段中存在空格、换行符等隐形字符,或者字段类型不统一(比如ID列同时存在字符串"1"和数值1),导致本来不同的行被识别为同一行,引发重复。
- 字段缺失值:如果
id_cols中的字段存在大量空值,会导致本来不同的行因为空值被识别为同一行,触发重复警告。
内容的提问来源于stack exchange,提问作者Ash S
相关产品推荐
相关产品推荐

