我正在尝试编写一个需要从结果数据框中排除用户传递变量的函数。我也借此机会更多地了解新的dplyr语法。
该函数的作用类似于数据帧的交叉连接。我想将它用作在函数参数之间复制数据的简洁方法。
该功能的工作原理如下:
crossjoin_df <- function(df1, df2, temp_col = ".k") {
df1 <- df1 %>%
mutate(!!temp_col := 1)
df2 <- df2 %>%
mutate(!!temp_col := 1)
out <- left_join(df1, df2, by = temp_col)
# I'm trying to replace the next line
out[,!names(out)==temp_col]
}
params <- data.frame(k = c(11,10),
n = c(27,26))
data <- data.frame(a = 1:3,
b = 4:6)
crossjoin_df(params, data) # 6 row data set
我想看看是否可以用管道选择语句替换最后一个语句。但是,这种否定似乎没有起作用。
我能得到类似的东西:
out %>% select(!!temp_col)
工作,但显然只选择.k
。我无法得到类似的东西:
out %>% select(-!!temp_col)
工作。
答案 0 :(得分:2)
你需要rlang,dplyr的后端包,它可以启用整齐的eval,无论你是否想继续使用字符串,在这种情况下你需要sym
将一个字符串变成一个字符串:
library(dplyr)
params <- data.frame(k = c(11,10),
n = c(27,26))
data <- data.frame(a = 1:3,
b = 4:6)
crossjoin_df <- function(df1, df2, temp_col = ".k") {
df1 <- df1 %>% mutate(!!temp_col := 1)
df2 <- df2 %>% mutate(!!temp_col := 1)
left_join(df1, df2, by = temp_col) %>%
select(-!!rlang::sym(temp_col))
}
crossjoin_df(params, data)
#> k n a b
#> 1 11 27 1 4
#> 2 11 27 2 5
#> 3 11 27 3 6
#> 4 10 26 1 4
#> 5 10 26 2 5
#> 6 10 26 3 6
...或切换到完整整洁的eval,在这种情况下,您需要quo_name
将quosure变为名称:
crossjoin_df <- function(df1, df2, temp_col = .k) {
temp_col <- enquo(temp_col)
df1 <- df1 %>% mutate(!!rlang::quo_name(temp_col) := 1)
df2 <- df2 %>% mutate(!!rlang::quo_name(temp_col) := 1)
left_join(df1, df2, by = rlang::quo_name(temp_col)) %>%
select(-!!temp_col)
}
crossjoin_df(params, data)
#> k n a b
#> 1 11 27 1 4
#> 2 11 27 2 5
#> 3 11 27 3 6
#> 4 10 26 1 4
#> 5 10 26 2 5
#> 6 10 26 3 6
或者,只需使用tidyr::crossing
:
tidyr::crossing(params, data)
#> k n a b
#> 1 11 27 1 4
#> 2 11 27 2 5
#> 3 11 27 3 6
#> 4 10 26 1 4
#> 5 10 26 2 5
#> 6 10 26 3 6
答案 1 :(得分:1)
您可以使用standalone.xml
,然后使用one_of
-
out %>% select(-one_of(temp_col))
答案 2 :(得分:0)
这也应该有效:
out %>% select_(paste0("-",temp_col))