按字符列名筛选数据帧(以dplyr为单位)
我有一个数据帧,希望通过两种方式之一对其进行过滤,即“this”列或“that”列。我希望能够将列名作为变量引用。如何(在按字符列名筛选数据帧(以dplyr为单位),r,dplyr,R,Dplyr,我有一个数据帧,希望通过两种方式之一对其进行过滤,即“this”列或“that”列。我希望能够将列名作为变量引用。如何(在dplyr中,如果有区别的话)通过变量引用列名 library(dplyr) df <- data.frame(this = c(1, 2, 2), that = c(1, 1, 2)) df # this that # 1 1 1 # 2 2 1 # 3 2 2 df %>% filter(this == 1) # t
dplyr
中,如果有区别的话)通过变量引用列名
library(dplyr)
df <- data.frame(this = c(1, 2, 2), that = c(1, 1, 2))
df
# this that
# 1 1 1
# 2 2 1
# 3 2 2
df %>% filter(this == 1)
# this that
# 1 1 1
如何将
列的值
转换为列名?我将避免同时使用get()
。在这种情况下,这似乎是相当危险的,特别是如果你正在编程的话。您可以使用未计算的调用或粘贴的字符串,但需要使用filter()
而不是filter()
选项2-使用粘贴()
(显然更简单):
关于这两个选项的主要内容是我们需要使用filter\uuz()
而不是filter()
。事实上,从我所读到的内容来看,如果您使用dplyr
编程,您应该始终使用*.\u()
函数
我用这篇文章作为一个有用的参考:,我用的是
dplyr
0.3.0.2版。关于Richard的解决方案,只想补充一点,如果你的专栏是字符。您可以添加shQuote
以按字符值筛选
例如,您可以使用
df %>% filter_(paste(column, "==", shQuote("a")))
如果您有多个筛选器,可以在粘贴中指定collapse=“&”
df %>$ filter_(paste(c("column1","column2"), "==", shQuote(c("a","b")), collapse = "&"))
从当前dplyr帮助文件(我强调):
dplyr用于提供每个动词的两个版本,每个版本的后缀为下划线。这些版本具有标准的求值(SE)语义:它们不像NSE动词那样按代码获取参数,而是按值获取参数。他们的目的是使使用dplyr编程成为可能。但是,dplyr现在使用整洁的求值语义。NSE动词仍然捕获它们的参数,但是现在可以取消这些参数的部分引用。这提供了NSE谓词的完整编程功能。因此,带下划线的版本现在是多余的
因此,我们基本上需要做两件事,才能在dplyr::filter()
中引用变量列的值“this”
:
我们需要将字符类型的变量列
转换为字符类型。
使用base R,这可以通过函数as.symbol()
它是as.name()
的别名。前者是
因为它
遵循更现代的术语(R类型而不是S模式)
或者,也可以通过从tidyverse获得相同的结果
我们需要从1中取消引用符号)。
不引用的确切含义可以在小插曲中学习
.
这是通过实现的代码>
(在早期版本的dplyr
(或底层的rlang
)中,曾经有!!
与单个!
冲突的情况(包括您的情况),但这不再是问题。)
适用于您的示例:
library(dplyr)
df <- data.frame(this = c(1, 2, 2),
that = c(1, 1, 2))
column <- "this"
df %>% filter(!!as.symbol(column) == 1)
# this that
# 1 1 1
库(dplyr)
df与上文解释的Salim B相似,但略有变化:
df %>% filter(1 == !!as.name(column))
i、 e.只需反转条件,因为代码>否则将正常工作
像
以下是最新dplyr版本的另一个解决方案:
df <- data.frame(this = c(1, 2, 2),
that = c(1, 1, 2))
column <- "this"
df %>% filter(.[[column]] == 1)
# this that
#1 1 1
df或在
library(dplyr)
df %>%
filter_at(vars(column), any_vars(. == 1))
最新的方法是使用my.data.frame%>%过滤器(.data[[myName]]==1)
,其中myName
是包含列名的环境变量。为什么要这样做?试图参数化变量的选择?我有一个数据集,其中包含两种类型的内容,每种类型有不同的列。我想以这种方式处理问题,因为我使用Shiny来制作交互式可视化,我想让人们选择要查看的对象类型,然后使用相同的代码来提取数据,根据他们的选择输入列名。几乎发布了我的问题,发现:)选项1是一个强大的解决方案,正如@hadley在SO和vignette(“nse”)的几篇文章中所建议的那样。然而,它似乎与哈德利优雅的函数调用风格背道而驰。它不能以更简单的方式包装和呈现吗?为什么get()被认为是危险的?这对于较旧版本的dpylr
来说是一个很好的答案,但是下划线函数已经被弃用,因此@Salim-B下面的答案更好。对于后一种情况,您可以使用一些额外的圆括号df%>%filter((!!as.name(column))==1)
Great,但是“'UQ()'和'UQS()”在rlang 0.2.0中被软性弃用,以使准旋转的语法更加一致。”感谢@ggll,我更新了答案,以说明dplyr/rlang最近的改进。
library(dplyr)
df <- data.frame(this = c(1, 2, 2),
that = c(1, 1, 2))
column <- "this"
df %>% filter(!!as.symbol(column) == 1)
# this that
# 1 1 1
df %>% filter(1 == !!as.name(column))
!!(as.name(column)==1)
df <- data.frame(this = c(1, 2, 2),
that = c(1, 1, 2))
column <- "this"
df %>% filter(.[[column]] == 1)
# this that
#1 1 1
library(dplyr)
df %>%
filter_at(vars(column), any_vars(. == 1))