6

我正在编写我的函数,并想使用 dplyr 的 filter() 函数来选择满足条件的数据帧行。这是我的代码:

library(tidyverse)

df <-data.frame(x = sample(1:100, 50), y = rnorm(50), z = sample(1:100,50), w = sample(1:100, 50),
            p = sample(1:100,50))

new <- function(ang,brad,drau){
  df%>%filter(!!drau %in% 1:50)%>%select(ang,brad) -> A
return(A)
}

brand <- c("z","w","p")
lapply(1:3, function(i) new(ang = "x", brad = "y", drau = brand[i]))%>%bind_rows()

每当我运行此函数时,似乎filter都没有选择任何满足条件的行。

我怎样才能使这项工作?

更新

出于某种原因,这在我不使用 `%in%, as in; 时有效。

new <- function(ang,brad,drau){
  df%>%filter(!!drau > 50)%>%select(ang,brad) -> A
return(A)
}

lapply(1:3, function(i) new(ang = "x", brad = "y", drau = brand[i]))%>%bind_rows()

但是,每个循环的结果都是相同的。为什么会这样?还有为什么我不能使用%in%.

4

4 回答 4

9

我同意@hrbrmstr 的标准评估解决方案。正如@hadley今天所建议的,这里是 NSE 解决方案:

library(tidyverse)

df <-data.frame(x = sample(1:100, 50), 
                y = rnorm(50), 
                z = sample(1:100,50), 
                w = sample(1:100, 50),
                p = sample(1:100,50))

new <- function(ang, brad, drau){
  ang  <- enquo(ang)
  brad <- enquo(brad)
  drau <- enquo(drau)

  df %>% filter(UQ(drau) %in% 1:50) %>%
    select(UQ(ang),UQ(brad)) 
}

brand <- c("z","w","p")
brand <- rlang::syms(brand)

map_df(brand, ~new(ang = x, brad = y, drau = UQ(.x)))
于 2017-07-21T10:35:14.290 回答
8

这似乎可以满足您的要求(但需要您确认):

library(tidyverse)
library(rlang)

set.seed(1492)

xdf <- data_frame(
  x = sample(1:100, 50),
  y = rnorm(50), 
  z = sample(1:100,50), 
  w = sample(1:100, 50),
  p = sample(1:100,50)
)

new_df <- function(ang, brad, drau) {
  drau <- sym(drau)
  filter(xdf, UQE(drau) %in% 1:50) %>% 
    select(ang, brad)
}

brand <- c("z", "w", "p")

map_df(brand, ~new_df(ang = "x", brad = "y", drau = .x))

尽管有大量使用 的“官方”“tidyverse”示例df,但它是 pkg 中的一个函数,stats我尽量避免再使用它。

既然您使用的是 tidyverse,不妨利用map_df()from purrr

于 2017-07-21T03:32:13.307 回答
1

现在UQE已弃用,此问题的公认答案将不起作用。这个答案应该有效。这里唯一的变化是!!sym()

library(rlang)
library(tidyverse)

df <-data.frame(x = sample(1:100, 50), y = rnorm(50), z = sample(1:100,50), w = sample(1:100, 50),
                p = sample(1:100,50))

new <- function(ang,brad,drau){
  df%>%filter(!!sym(drau) %in% 1:50)%>%select(!!sym(ang), !!sym(brad)) -> A
  return(A)
}

brand <- c("z","w","p")
lapply(1:3, function(i) new(ang = "x", brad = "y", drau = brand[i]))%>%bind_rows()

如果您不想将函数参数作为字符串传递,请!!enquo()改用。

new <- function(ang,brad,drau){
  df%>%filter(!!enquo(drau) %in% 1:50)%>%select(!!enquo(ang), !!enquo(brad)) -> A
  return(A)
}

> head(new(ang = x, brad = y, drau = z))
    x           y
1  44  0.47702540
2  84 -1.09670409
3  59 -0.20556334
4  81 -0.46306635
5  93  1.36845485
6   8  0.37392587
于 2020-04-08T22:04:21.163 回答
0

我有一个类似的问题,对我有用的简单解决方法是在“过滤器”动词中使用“.data”代词,特别是在这种情况下:

filter(.data[[drau]] %in% 1:50)

更多信息在这里:https : //tinyheero.github.io/2020/03/01/use-data-env-pronouns-tidyverse.html 最近莱昂内尔亨利在 Rstudio 的 youtube 频道上的谈话也很有帮助。

library(tidyverse)

df <-data.frame(x = sample(1:100, 50), y = rnorm(50), z = sample(1:100,50), w = sample(1:100, 50),
                p = sample(1:100,50))

new <- function(ang,brad,drau){
  df%>%filter(.data[[drau]] %in% 1:50)%>%select(ang,brad) -> A
  return(A)
}

brand <- c("z","w","p")
lapply(1:3, function(i) new(ang = "x", brad = "y", drau = brand[i]))%>%bind_rows()

希望有人在这方面找到一些用处。

于 2021-02-19T09:57:28.440 回答