使用与列名称相同的全局变量过滤数据框

Mar*_*rco 9 r dplyr

library(dplyr)
Run Code Online (Sandbox Code Playgroud)

玩具数据集:

df <- data.frame(x = c(1, 2, 3), y = c(4, 5, 6))
df
  x y
1 1 4
2 2 5
3 3 6
Run Code Online (Sandbox Code Playgroud)

这很好用:

df %>% filter(y == 5)
  x y
1 2 5
Run Code Online (Sandbox Code Playgroud)

这也很好:

z <- 5
df %>% filter(y == z)
  x y
1 2 5
Run Code Online (Sandbox Code Playgroud)

但这失败了

y <- 5
df %>% filter(y == y)
  x y
1 1 4
2 2 5
3 3 6
Run Code Online (Sandbox Code Playgroud)

显然,dplyr无法区分其列y和全局变量y.有没有办法告诉dplyr第二个y是全局变量?

Spa*_*man 11

你可以做:

df %>% filter(y == .GlobalEnv$y)
Run Code Online (Sandbox Code Playgroud)

要么:

df %>% filter(y == .GlobalEnv[["y"]])
Run Code Online (Sandbox Code Playgroud)

要么:

两者都在这种情况下工作,但如果所有这一切都在一个函数内部进行,则不会.但是get会:

df %>% filter(y == get("y"))
f = function(df, y){df %>% filter(y==get("y"))}
Run Code Online (Sandbox Code Playgroud)

所以使用get.

或者只是使用df[df$y==y,] 而不是 dplyr.


Hon*_*Ooi 6

可以通过.GlobalEnv对象访问全局环境:

> filter(df, y==.GlobalEnv$y)
  x y
1 2 5
Run Code Online (Sandbox Code Playgroud)

有趣的是,使用访问器函数globalenv()作为替代品.GlobalEnv在这种情况下不起作用.

  • `globalenv()`失败,因为任何带有'$ y`的函数调用都会失败,因为`dplyr`似乎对像`foo()$ y`这样的表达式做了一些坏事,如果你的数据中有`y`帧.可怕. (3认同)
  • 另一方面,`globalenv()[["y"]]` 确实有效。总是出现问题的`$`。 (2认同)
  • @Spacedman NSE没有任何关系,间接保存.例如,`subset(df,y == globalenv()$ y)`有效.这只是dplyr中一个很好的老式错误. (2认同)