如何通过多个灵活的条件过滤列
How to filter a column by multiple, flexible criteria
我正在编写一个函数来聚合数据框,它需要普遍适用于各种数据集。此函数的一个步骤是 dplyr 的 filter
函数,用于从数据中 select 仅与手头任务相关的广告活动类型。因为我需要函数灵活,所以我希望 ad_campaign_types 作为输入,但这使得过滤有点毛茸茸,如下所示:
aggregate_data <- function(ad_campaign_types) {
raw_data %>%
filter(ad_campaign_type == ad_campaign_types) -> agg_data
agg_data
}
new_data <- aggregate_data(ad_campaign_types = c("campaign_A", "campaign_B", "campaign_C"))
我认为上面的方法会起作用,但是当它运行时,奇怪的是它只 returns 只是过滤数据集应该是的一小部分。有更好的方法吗?
另一个可替换代码的小例子:
ad_types <- c("a", "a", "a", "b", "b", "c", "c", "c", "d", "d")
revenue <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
data <- as.data.frame(cbind(ad_types, revenue))
# Now, filtering to select only ad types "a", "b", and "d",
# which should leave us with only 7 values
new_data <- filter(data, ad_types == c("a", "b", "d"))
nrow(new_data)
[1] 3
对于多个条件,使用 %in%
函数:
filter(data, ad_types %in% c("a", "b", "d"))
你也可以使用"not in"标准:
filter(data, !(ad_types %in% c("a", "b", "d")))
但是请注意 %in%
的行为与 ==
略有不同:
> c(2, NA) == 2
[1] TRUE NA
> c(2, NA) %in% 2
[1] TRUE FALSE
有些人发现其中一个比另一个更直观,但您必须记住其中的区别。
至于使用多个不同的标准,只需使用带有 and/or 语句的标准链:
filter(mtcars, cyl > 2 & wt < 2.5 & gear == 4)
Tim 可以正确过滤数据帧。但是,如果你想用 dplyr 做一个函数,你需要按照这个网页上的说明进行操作:https://rpubs.com/hadley/dplyr-programming.
我建议的代码。
library(tidyverse)
ad_types <- c("a", "a", "a", "b", "b", "c", "c", "c", "d", "d")
revenue <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
df <- data_frame(ad_types = as.factor(ad_types), revenue = revenue)
aggregate_data <- function(df, ad_types, my_list) {
ad_types = enquo(ad_types) # Make ad_types a quosure
df %>%
filter(UQ(ad_types) %in% my_list) # Unquosure
}
new_data <- aggregate_data(df = df, ad_types = ad_types,
my_list = c("a", "b", "c"))
应该可以!
我正在编写一个函数来聚合数据框,它需要普遍适用于各种数据集。此函数的一个步骤是 dplyr 的 filter
函数,用于从数据中 select 仅与手头任务相关的广告活动类型。因为我需要函数灵活,所以我希望 ad_campaign_types 作为输入,但这使得过滤有点毛茸茸,如下所示:
aggregate_data <- function(ad_campaign_types) {
raw_data %>%
filter(ad_campaign_type == ad_campaign_types) -> agg_data
agg_data
}
new_data <- aggregate_data(ad_campaign_types = c("campaign_A", "campaign_B", "campaign_C"))
我认为上面的方法会起作用,但是当它运行时,奇怪的是它只 returns 只是过滤数据集应该是的一小部分。有更好的方法吗?
另一个可替换代码的小例子:
ad_types <- c("a", "a", "a", "b", "b", "c", "c", "c", "d", "d")
revenue <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
data <- as.data.frame(cbind(ad_types, revenue))
# Now, filtering to select only ad types "a", "b", and "d",
# which should leave us with only 7 values
new_data <- filter(data, ad_types == c("a", "b", "d"))
nrow(new_data)
[1] 3
对于多个条件,使用 %in%
函数:
filter(data, ad_types %in% c("a", "b", "d"))
你也可以使用"not in"标准:
filter(data, !(ad_types %in% c("a", "b", "d")))
但是请注意 %in%
的行为与 ==
略有不同:
> c(2, NA) == 2
[1] TRUE NA
> c(2, NA) %in% 2
[1] TRUE FALSE
有些人发现其中一个比另一个更直观,但您必须记住其中的区别。
至于使用多个不同的标准,只需使用带有 and/or 语句的标准链:
filter(mtcars, cyl > 2 & wt < 2.5 & gear == 4)
Tim 可以正确过滤数据帧。但是,如果你想用 dplyr 做一个函数,你需要按照这个网页上的说明进行操作:https://rpubs.com/hadley/dplyr-programming.
我建议的代码。
library(tidyverse)
ad_types <- c("a", "a", "a", "b", "b", "c", "c", "c", "d", "d")
revenue <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
df <- data_frame(ad_types = as.factor(ad_types), revenue = revenue)
aggregate_data <- function(df, ad_types, my_list) {
ad_types = enquo(ad_types) # Make ad_types a quosure
df %>%
filter(UQ(ad_types) %in% my_list) # Unquosure
}
new_data <- aggregate_data(df = df, ad_types = ad_types,
my_list = c("a", "b", "c"))
应该可以!