如何用R语言根据DV值将评分写入对应目标列?
问题
现有长格式数据结构如下:
dats_long <- data.frame (dv = c("Unt", "Dis", "Emp"), rating = c(100, 53, 99), unt = c(NA, NA, NA), dis = c(NA, NA, NA), emp = c(NA, NA, NA))
每个观测对应vignette survey中的一个因变量(DV)评分,评分存储在rating列中。需要将unt、dis、emp三列填充为对应DV的评分值,目标输出如下:
dats_long <- data.frame (dv = c("Unt", "Dis", "Emp"), rating = c(100, 53, 99), unt = c(100, NA, NA), dis = c(NA, 53, NA), emp = c(NA, NA, 99))
尝试过两种方法均未成功:
- 使用
dplyr::case_when,未写入数据:
dats_long %>% mutate(dis = case_when( dv == "Dis" ~ rating ))
- 基础R索引赋值,会将
rating所有值写入,导致数据错位:
dats_long$dis[dats_long$dv == "Dis"] <- dats_long$rating
解决方案
方法1:dplyr批量处理(推荐)
用across遍历目标列,统一大小写后匹配列名与dv的值,符合条件时填充rating:
library(dplyr) dats_long <- dats_long %>% mutate(across(c(unt, dis, emp), ~if_else(tolower(dv) == cur_column(), rating, .x)))
cur_column()获取当前处理的列名,tolower将dv的大写转为小写,避免大小写不匹配导致的填充失败。
方法2:基础R循环实现
无需额外包,直接循环处理每一列:
target_cols <- c("unt", "dis", "emp") for (col in target_cols) { dats_long[[col]] <- ifelse(tolower(dats_long$dv) == col, dats_long$rating, dats_long[[col]]) }
循环每个目标列,判断当前行dv小写后是否等于列名,是则赋值rating,否则保留原NA。
方法3:宽转格式合并
先将dv和rating转为宽格式,再与原数据合并:
library(tidyr) library(dplyr) # 生成宽格式评分列 wide_rating <- dats_long %>% select(dv, rating) %>% mutate(dv = tolower(dv)) %>% pivot_wider(names_from = dv, values_from = rating) # 合并到原数据 dats_long <- dats_long %>% select(-unt, -dis, -emp) %>% bind_cols(wide_rating)
先提取有效数据转成宽格式,再替换原数据中的空列,同样能得到目标结果。
内容的提问来源于stack exchange,提问作者Heiko Westerburg
相关产品推荐
相关产品推荐

