You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

R语言中` `、' '与" "的区别及dplyr列名过滤问题

R语言中反引号、单引号和双引号的区别及dplyr使用问题解析

刚好碰到过类似的场景,我来给你理清楚这三种引号的核心区别,以及你用filter()时遇到的问题到底是怎么回事~

一、三种引号的各司其职

先把每个引号的作用掰明白:

  • 反引号( :这是R专门用来处理「不听话」的对象名的——比如列名里有空格、特殊字符(像你这里的á、ó)、括号,或者和R内置函数重名的情况。它的核心作用是告诉R:“别把这个当代码,这就是个对象/列的名字!”。比如Variável (Código)这种不符合R标准命名规则的列名,必须用反引号包裹才能被正确识别。
  • 单引号(' ')和双引号(" "):这俩在R里完全等价,都是用来定义字符串字面量的。唯一的小技巧是,如果字符串本身包含双引号,用单引号包裹就不用转义(比如'She said "I love R"'),反之亦然,仅此而已。

二、为什么你的反引号写法会失败?

你遇到的问题其实和引号本身没关系,问题出在dplyr的**非标准求值(NSE)**机制上。
dplyr的filter()默认会把你写的表达式(比如Variável (Código) == "8677")直接解析,它会在当前环境里找这个列名的绑定。但你是通过嵌套列表(pms$releases$date_201803$table_6443)直接访问数据框的,这种情况下dplyr的NSE没办法正确定位到嵌套数据框里的列名,自然就识别不了反引号包裹的内容了。

而你用!!as.name(colunas[1])能成功,是因为你手动把字符串转换成了R能识别的「名字对象」,然后用!!(解引用操作符)告诉dplyr:“别解析这个表达式,直接把它当成列名用”,相当于绕过了NSE的自动解析逻辑,所以能正常工作。

三、更简洁的解决方法

其实不用绕这么大弯,有两种更直接的方式解决这个问题:

  1. .data代词明确指定数据源:dplyr提供了.data代词,专门用来告诉函数“从当前数据框里取列”,不管列名多复杂都能搞定:
pms$releases$date_201803$table_6443 %>% 
  filter(.data[["Variável (Código)"]] == "8677", 
         .data[["Tipos de índice (Código)"]] %in% c("40311", "40312"))
  1. 先把数据框赋值给变量:避免嵌套访问,让dplyr的NSE能正常识别列名:
my_table <- pms$releases$date_201803$table_6443
my_table %>% 
  filter(`Variável (Código)` == "8677", 
         `Tipos de índice (Código)` %in% c("40311", "40312"))

这样反引号就能正常生效了,因为dplyr现在能明确从my_table这个变量指向的数据框里找列名。

四、一句话总结

  • 反引号管「识别特殊列名/对象名」,单双引号管「定义字符串」,三者功能完全不同,不能随便互换;
  • 嵌套数据框里用dplyr函数时,要么用.data代词明确数据源,要么先把数据框存成变量,就能解决列名识别的问题。

内容的提问来源于stack exchange,提问作者motabe

火山引擎 最新活动