R语言如何用for循环实现:function(x)返回NA时用function(y)输出替换
R语言用for循环实现多列姓名优先级性别识别
背景
我在使用R的gender包识别数据集中姓名对应的性别时,数据里部分人员带有中间名,希望利用这部分信息优化识别结果。gender::gender()函数基于历史数据识别姓名性别(需要配套安装genderdata包),有匹配记录时会返回姓名对应性别占比的详细结果,无匹配记录时返回空值。
核心需求
编写功能逻辑,先对主姓名列调用gender()识别性别,若返回空值则调用中间名列做识别,用中间名的识别结果替换空值,最终输出同时包含原始gender()识别结果和优化后结果的数据集。
依赖安装
# 加载所需包 library(tidyverse) library(gender) library(genderdata) # 若安装gender包出错,可尝试以下命令从GitHub安装: devtools::install_github("ropensci/gender") devtools::install_github("lmullen/gender-data-pkg")
现有自定义函数版本
之前已经实现了支持最多3个优先级姓名的识别函数:
gender_2 <- function(x, y=NULL, z=NULL){ g_1 <- gender::gender(as.character(x), method = "ipums") %>% select(name, gender) if (nrow(g_1) > 0) { g_1 } else { if (missing(y)) { g_1 } else { g_2 <- gender::gender(as.character(y), method = "ipums") %>% select(name, gender) if (nrow(g_2) > 0) { g_2 } else { if (missing(z)) { g_1 } else { g_3 <- gender::gender(as.character(z), method = "ipums") %>% select(name, gender) g_3 } } } } }
for循环实现方案
思路:逐行遍历数据集,按优先级调用姓名识别,结果直接存入新列:
# 示例数据集 df <- tibble(name_1 = c("abc", "John", "xyz"), name_2 = c("Peter", "Mary", "Anna")) # 初始化结果列 df$gender <- NA_character_ # 原始主姓名识别结果 df$gender_2 <- NA_character_ # 优化后识别结果 # for循环逐行处理 for (i in 1:nrow(df)) { # 先识别主姓名 res_main <- gender::gender(as.character(df$name_1[i]), method = "ipums") # 存原始识别结果 df$gender[i] <- ifelse(nrow(res_main) > 0, res_main$gender, NA) # 优化逻辑:主姓名无结果则用中间名 if (nrow(res_main) > 0) { df$gender_2[i] <- res_main$gender } else { res_alt <- gender::gender(as.character(df$name_2[i]), method = "ipums") df$gender_2[i] <- ifelse(nrow(res_alt) > 0, res_alt$gender, NA) # 如果有第三优先级姓名,可在此处加else判断继续调用 } } # 查看输出结果 df
运行后输出和预期一致:
# A tibble: 3 × 4 name_1 name_2 gender gender_2 <chr> <chr> <chr> <chr> 1 abc Peter NA male 2 John Mary male male 3 xyz Anna NA female
内容的提问来源于stack exchange,提问作者Dr. Fabian Habersack
相关产品推荐
相关产品推荐

