R语言中mean()函数在case_when及管道中使用失效的原因咨询
按性别填充泰坦尼克号年龄缺失值的代码问题解析
问题背景
我是R语言初学者,正在使用tidyverse中的titanic训练数据集做dplyr数据处理练习,需求是按性别填充乘客年龄的缺失值(用对应性别的平均年龄)。现有可行代码,但尝试简化写法时遇到两个问题,下面分别解释两种错误写法失效的原因。
可行代码
#' Exercise 6.5 #' 使用case_when函数在titanic数据集中创建名为imputed_age_of_passenger的新列。 #' 当乘客性别为“male”且年龄缺失时,用男性乘客的平均年龄填充; #' 当乘客性别为“female”且年龄缺失时,用女性乘客的平均年龄填充; #' 其他情况保留原年龄值。 mean_age_male <- titanic %>% filter(sex_of_passenger == "male") %>% pull(age_of_passenger) %>% mean(na.rm = TRUE) mean_age_female <- titanic %>% filter(sex_of_passenger == "female") %>% pull(age_of_passenger) %>% mean(na.rm = TRUE) titanic <- titanic %>% mutate(imputed_age_of_passenger = case_when( sex_of_passenger == "male" & is.na(age_of_passenger) ~ mean_age_male, sex_of_passenger == "female" & is.na(age_of_passenger) ~ mean_age_female, TRUE ~ age_of_passenger))
错误写法1:mutate中嵌套filter与mean的语法错误
错误代码
titanic <- titanic %>% mutate(imputed_age_of_passenger = case_when( sex_of_passenger == "male" & is.na(age_of_passenger) ~ mean(filter(sex_of_passenger == "male")$age_of_passenger, na.rm = TRUE), sex_of_passenger == "female" & is.na(age_of_passenger) ~ mean(filter(sex_of_passenger == "female")$age_of_passenger, na.rm = TRUE) TRUE ~ age_of_passenger))
报错信息
Error: unexpected numeric constant in: " sex_of_passenger == "female" & is.na(age_of_passenger) ~ mean(filter(sex_of_passenger == "female")$age_of_passenger, na.rm = TRUE) TRUE"
失效原因
- 语法缺失逗号:
case_when的每个条件行末尾必须用逗号分隔,第二个条件行结尾没有加逗号,直接衔接TRUE ~ age_of_passenger,导致R解析时把这两行当成同一行,触发语法错误。 - filter参数错误:
filter()函数的第一个参数必须是要筛选的数据集,这里直接写filter(sex_of_passenger == "male"),没有指定数据来源(正确写法应为filter(titanic, sex_of_passenger == "male")),即使补上逗号,R也找不到该变量的上下文,会报错提示对象'sex_of_passenger'未找到。
错误写法2:管道中pull与mean的调用顺序错误
错误代码
mean_age_male <- titanic %>% filter(sex_of_passenger == "male") %>% mean(pull(age_of_passenger), na.rm = TRUE)
警告信息
Warning message: In mean.default(., na.rm = TRUE) : argument is not numeric or logical: returning NA
失效原因
管道操作%>%的规则是:前一个步骤的输出会作为下一个函数的第一个参数传入。这里filter()之后得到的是一个数据框,传到mean()时,这个数据框会作为mean()的第一个参数(即.),而pull(age_of_passenger)被当成了mean()的第二个参数(但mean()的第二个参数是na.rm,要求是逻辑值,传入向量完全不符合要求)。
正确逻辑应该是先从数据框中提取age_of_passenger列得到数值向量,再计算均值,也就是必须先调用pull(),再调用mean(),而非把pull()作为mean()的参数。
内容的提问来源于stack exchange,提问作者Xavier Villà Aguilar
相关产品推荐
相关产品推荐

