R语言自定义函数中数据框$与[]列索引的差异问题
R语言函数内数据框索引写法差异问题
编写R自定义函数实现按指定列的因子值筛选行、提取数值列输出统计摘要时,两种逻辑看似一致的索引写法出现了运行差异:一种触发列不存在的警告无法正常运行,一种可以得到预期结果。
失效写法(使用$索引)
isola_por_fator_em_col <- function(data,col,fator) { y <- data[which(data$col==fator),] x <- select_if(y,is.numeric) summary(x) } # 非字符串形式传列名 isola_por_fator_em_col(data=desempenho_aluno_escola,col=priv,fator="privada") # 触发警告:Warning message: Unknown or uninitialised column: `col`. # 改为字符串形式传列名依然无法正常运行 isola_por_fator_em_col(data=desempenho_aluno_escola,col="priv",fator="privada")
正常运行写法(使用[]索引)
isola_por_fator_em_col <- function(data,col,fator) { y <- data[which(data[col]==fator),] x <- select_if(y,is.numeric) summary(x) } # 传入字符串形式列名可得到正确输出 isola_por_fator_em_col(data=desempenho_aluno_escola,col="priv",fator="privada")
正常运行的输出结果:
desempenho horas texp Min. : 11.40 Min. : 4.00 Min. : 9.0 1st Qu.: 51.42 1st Qu.:16.00 1st Qu.: 9.0 Median : 67.45 Median :21.00 Median :10.0 Mean : 66.55 Mean :20.06 Mean :13.3 3rd Qu.: 82.47 3rd Qu.:25.00 3rd Qu.:19.0 Max. :108.00 Max. :31.00 Max. :20.0
核心原因:$与[]的索引规则差异
两种写法表现不一致,本质是R语言中两种索引操作符的求值规则完全不同:
$为静态字面量匹配:$操作符后接的内容会被直接识别为固定列名,不会对传入的变量做解析求值。也就是说无论你给函数参数col传入什么值,data$col永远只会查找数据框中名称严格为col的列,自然会因为数据框中不存在该列触发警告。在函数外部直接运行desempenho_aluno_escola[which(desempenho_aluno_escola$priv=="privada"),]能正常生效,是因为代码直接把列名priv作为字面量写在了$后方,不存在变量传参、动态解析的步骤。[]为动态求值匹配:方括号内的传入内容会先被完整求值,再用求值得到的结果匹配列名。当传入参数col = "priv"时,data[col]会先将col解析为字符串"priv",再定位到数据框中对应的priv列,因此可以完美适配函数内动态传列名的场景。
补充:如果需要索引列后返回原子向量而非单列数据框,可以使用双中括号
[[ ]],data[[col]]的动态求值逻辑和单中括号一致,同样支持函数参数传参的场景。
内容的提问来源于stack exchange,提问作者Rafael Araújo
相关产品推荐
相关产品推荐

