R语言:基于zscore数据框为data创建BMI超标判断条件列
问题与解决方案
数据结构
data 数据框(约6000条观测)
> head(data) STATE MONTHS_AGE BMI 1 1 122 15.29162 2 1 114 18.58449 3 1 78 16.40888 4 1 113 22.25390 5 1 136 18.25913 6 1 85 14.24700
zscore 数据框(月龄阈值表)
> head(zscore) # A tibble: 168 × 2 Month SD2 <dbl> <dbl> 1 61 18.3 2 62 18.3 3 63 18.3 4 64 18.3 5 65 18.3 6 66 18.4 7 67 18.4 8 68 18.4 9 69 18.4 10 70 18.5
问题与错误分析
需要判断每个个体的BMI是否超过对应月龄的2倍标准差(即zscore中对应Month的SD2值),但原代码因数据框行数不匹配触发警告:
data <- data %>% mutate(obesity = MONTHS_AGE == zscore$Month & BMI > zscore$SD2)
警告信息:
Warning message: There were 2 warnings in `mutate()`. The first warning was: ℹ In argument: `data = MONTHS_AGE == zscore$Month & BMI > zscore$SD2`. Caused by warning in `MONTHS_AGE == zscore$Month`: ! longer object length is not a multiple of shorter object length ℹ Run dplyr::last_dplyr_warnings() to see the 1 remaining warning.
原因是两个数据框行数差异大,R会循环短向量匹配长向量,导致比对逻辑完全错误。
解决方案
方法1:先关联阈值再判断(推荐)
用left_join把zscore的对应月龄阈值匹配到data中,再新增判断列:
library(dplyr) # 匹配对应月龄的SD2阈值,新增判断列 data <- data %>% left_join(zscore, by = c("MONTHS_AGE" = "Month")) %>% mutate(obesity = BMI > SD2)
如果data存在zscore中没有的月龄,SD2会出现NA,可按需处理(比如设为FALSE):
data <- data %>% left_join(zscore, by = c("MONTHS_AGE" = "Month")) %>% mutate(obesity = ifelse(is.na(SD2), FALSE, BMI > SD2))
方法2:用match函数直接匹配阈值
无需合并数据框,直接在mutate中通过match定位对应阈值后判断:
data <- data %>% mutate( # 提取对应月龄的SD2阈值 sd2_threshold = zscore$SD2[match(MONTHS_AGE, zscore$Month)], obesity = BMI > sd2_threshold )
同样,无匹配月龄的sd2_threshold会是NA,可通过ifelse统一处理。
内容的提问来源于stack exchange,提问作者TheMarcorojo
相关产品推荐
相关产品推荐

