@Aurele已经展示了如何使用rlang来实现它,但我想看看我们是否可以使用
get
也正如我所指出的
收到
不起作用,但经过一些实验后,这似乎如预期的那样起作用。这并不是说我在建议这一点,而是出于兴趣的考虑。
1、获取/执行
如果我们用
do
然后我们可以使用
get(..., .)
像这样,它将按需要工作。这可能是最简单、最直接的使用方法
收到
在内部
group by
. 关键的观察结果是
做
点指的是当前组内的行,而不是
做
当在嵌套函数调用的实际参数中使用时,它引用输入的所有行。
find_dataset_inconsistencies <- function(df, target_column, cols_to_use) {
df %>%
group_by_at(cols_to_use) %>%
do(summarise(., uTargets = length(unique(get(target_column, .))))) %>%
filter(uTargets > 1)
}
# gives desired result
find_dataset_inconsistencies(mtcars, "mpg", c("cyl", "vs", "am", "gear", "carb"))
# ... snip correct output ...
# correctly gives an error indicating it can't find `foo`
foo <- 3
find_dataset_inconsistencies(mtcars, "foo", c("cyl", "vs", "am", "gear", "carb"))
2、与祖父母接触继承=假
find_dataset_inconsistencies <- function(df, target_column, cols_to_use) {
df %>%
group_by_at(cols_to_use) %>%
summarise(uTargets = length(unique(get(target_column,
parent.env(parent.env(environment())), inherits = FALSE)))) %>%
filter(uTargets > 1)
}
# gives desired result
find_dataset_inconsistencies(mtcars, "mpg", c("cyl", "vs", "am", "gear", "carb"))
# ... snip correct output ...
# correctly gives an error indicating it can't find `foo`
foo <- 3
find_dataset_inconsistencies(mtcars, "foo", c("cyl", "vs", "am", "gear", "carb"))
## Error in summarise_impl(.data, dots) :
## Evaluation error: object 'foo' not found.
为了使此解决方案更加精简,我们可以定义
GET
这样地:
GET <- function(x) {
p <- parent.frame()
p3 <- parent.env(parent.env(p))
get(x, p3, inherits = FALSE)
}
find_dataset_inconsistencies <- function(df, target_column, cols_to_use) {
df %>%
group_by_at(cols_to_use) %>%
summarise(uTargets = length(unique(GET(target_column)))) %>%
filter(uTargets > 1)
}
# gives expected answer
find_dataset_inconsistencies(mtcars, "mpg", c("cyl", "vs", "am", "gear", "carb"))
# gives expected error
foo <- 3
find_dataset_inconsistencies(mtcars, "foo", c("cyl", "vs", "am", "gear", "carb"))
3、按键列子集
另一种可能性是通过键列进行子集。
mtcars
没有这样的列,但如果我们将行名称设置为这样的列,则会有一个:
library(tidyr)
find_dataset_inconsistencies <- function(df, target_column, cols_to_use) {
df %>%
rownames_to_column %>%
group_by_at(cols_to_use) %>%
summarise(uTargets = length(unique(
get(target_column, .[.$rowname %in% rowname, ])))) %>%
filter(uTargets > 1)
}
# gives expected answer
find_dataset_inconsistencies(mtcars, "mpg", c("cyl", "vs", "am", "gear", "carb"))
# gives expected error
find_dataset_inconsistencies(mtcars, "foo", c("cyl", "vs", "am", "gear", "carb"))