我想使用dplyr> = 0.7删除列向量
library(dplyr)
data(mtcars)
rem_cols <- c("wt", "qsec", "vs", "am", "gear", "carb")
head(select(mtcars, !!paste0("-", rem_cols)))
Run Code Online (Sandbox Code Playgroud)
错误:字符串必须与列名匹配.未知列:-wt,-qsec,-vs,-am,-gear,-carb
dplyr <0.7的工作原理如下:
head(select_(mtcars, .dots = paste0("-", rem_cols)))
# mpg cyl disp hp drat
# Mazda RX4 21.0 6 160 110 3.90
# Mazda RX4 Wag 21.0 6 160 110 3.90
# Datsun 710 22.8 4 108 93 3.85
# Hornet 4 Drive 21.4 6 258 110 3.08
# Hornet Sportabout 18.7 8 360 175 3.15
# Valiant 18.1 6 225 105 2.76
Run Code Online (Sandbox Code Playgroud)
我已经尝试了所有rlang的组合:syms(),!!,!!!,quo和enquo,我能想到......帮助!?
我无法找到dplyr 0.7替换将被弃用的mutate_函数的方法.
该mutate_功能在我的使用情况是有用的:我存储在数据库(字符串格式)许多指令(即如果需要,可以过滤),并应用这些指令到一个或几个数据帧.
例如 :
dplyr::tibble(test = "test@test") %>%
dplyr::mutate_(.dots = list("test2" = "substr(test, 1, 5)",
"test3" = "substr(test, 5, 5)"))
Run Code Online (Sandbox Code Playgroud)
有没有办法用dplyr 0.7保存变量和指令作为字符?
我想将dplyr的编程魔术(新于0.7.0版)用于coalesce两列。在下面,我列出了一些尝试。
df <- data_frame(x = c(1, 2, NA), y = c(2, NA, 3))
# What I want to do:
mutate(df, y = coalesce(x, y))
# Here's the expected output:
#> # A tibble: 3 x 2
#> x y
#> <dbl> <dbl>
#> 1 1 1
#> 2 2 2
#> 3 NA 3
Run Code Online (Sandbox Code Playgroud)
我以为fn1可以用,但是它varname在右侧被视为角色。
fn1 <- function(varname) {
mutate(df, UQ(varname) := coalesce(x, !!varname))
}
fn1("y")
# Error in mutate_impl(.data, dots) : …Run Code Online (Sandbox Code Playgroud) 我正在尝试实施我在网上找到的建议,但我已经走到了我想去的地方。
这是一个可重现的示例:
library(tidyverse)
library(dplyr)
library(rlang)
data(mtcars)
filter_expr = "am == 1"
mutate_expr = "gear_carb = gear*carb"
select_expr = "mpg , cyl"
mtcars %>% filter_(filter_expr) %>% mutate_(mutate_expr) %>% select_(select_expr)
Run Code Online (Sandbox Code Playgroud)
该过滤器表达式工作正常。
在发生变异表达的作品很好,但新的变量名称gear_carb =齿轮*碳水化合物,而不是预期的gear_carb。
最后,select表达式返回一个异常。
我有一个自定义函数,我正在从数据框中读取输入的变量rlang.无论输入的参数是引用还是不引用,此函数都可以正常工作.但是,奇怪的是,当使用此函数时purrr::pmap,它仅在引用参数时起作用.
所以我有两个问题:
为什么函数行为这样?
如何使用rlang这样一个函数,即使用于我也不必引用参数purrr::pmap?
这是一个使用简单函数突出显示此问题的最小代表:
# loading the needed libraries
library(rlang)
library(dplyr)
library(purrr)
# defining the function
tryfn <- function(data, x, y) {
data <-
dplyr::select(
.data = data,
x = !!rlang::enquo(x),
y = !!rlang::enquo(y)
)
# creating a dataframe of means
result_df <- data.frame(mean.x = mean(data$x), mean.y = mean(data$y))
# return the dataframe
return(result_df)
}
# without quotes (works!)
tryfn(iris, Sepal.Length, Sepal.Width)
#> mean.x mean.y
#> 1 5.843333 3.057333 …Run Code Online (Sandbox Code Playgroud) 我正在编写一个使用 tidyverse 函数的包,即使用非标准评估,dplyr::filter例如:
setMethod("filter_by_id",
signature(x = "studies", id = "character"),
definition = function(x, id) {
study_id <- rlang::expr(study_id)
lst <- purrr::map(s4_to_list(x), ~ dplyr::filter(.x, !!study_id %in% id))
y <- list_to_s4(lst, "studies")
return(y)
})
Run Code Online (Sandbox Code Playgroud)
我正在使用!!运算符(我可能会使用rlang包中的其他几个),我想知道是否需要像使用 pipe-operator%>%一样显式导入它,如以下问题中所述:R: use magrittr pipe operator in自己写的包。
有什么等价于usethis::use_pipe()但对于运营商 from rlang?
我正在foo使用map2和修改嵌套的数据框mutate,并且我想根据来在每个嵌套的数据框中命名一个变量foo$name。我不确定nse/ tidyeval取消引号的正确语法在这里。我的尝试:
library(tidyverse)
foo <- mtcars %>%
group_by(gear) %>%
nest %>%
mutate(name = c("one", "two", "three")) %>%
mutate(data = map2(data, name, ~
mutate(.x, !!(.y) := "anything")))
#> Error in quos(...): object '.y' not found
Run Code Online (Sandbox Code Playgroud)
我希望嵌套数据框中的新创建变量的名称分别为“一个”,“两个”和“三个”。
如果我对normal mutate进行普通操作df,那么我将基于普通语法使用我的尝试,name字符串在哪里:
name <- "test"
mtcars %>% mutate(!!name := "anything") # works fine
Run Code Online (Sandbox Code Playgroud)
如果成功,则以下行应返回TRUE:
foo[1,2] %>% unnest %>% names %>% .[11] == "one"
Run Code Online (Sandbox Code Playgroud) 在这个问题的最终目标是构建以下未评估使用呼叫[R “的计算上的语言,在那里list,a_name并50L从参数提供。
list(a_name = 50L)
Run Code Online (Sandbox Code Playgroud)
内部看起来像
str(quote(list(a_name = 50L)))
# language list(a_name = 50L)
str(as.list(quote(list(a_name = 50L))))
#List of 2
# $ : symbol list
# $ a_name: int 50
Run Code Online (Sandbox Code Playgroud)
我将把我的变量放在一个列表中,这样进一步的代码就会更清晰。
params = list(my_fun = as.name("list"), my_name = "a_name", my_value = 50L)
# What I tried so far?
# 1. The first thing that one would try
substitute(my_fun(my_name = my_value),
params)
#list(my_name = 50L) ## `my_name` was not substituted!
# 2. …Run Code Online (Sandbox Code Playgroud) 这是我在包中使用...参数并tidyselect选择变量的函数的简化版本:
# this toy function just selects the ... variables
foo <- function(dat = mtcars, ...){
expr <- rlang::expr(c(...))
cols_to_select <- tidyselect::eval_select(expr, data = dat)
dplyr::select(dat, all_of(cols_to_select))
}
Run Code Online (Sandbox Code Playgroud)
这有效: foo(mtcars, cyl)
但是我的实际函数在参数之前有更多前面的...参数,所有参数都有默认值。如果我使用这些默认值调用我的函数并将值传递给....
这就是我想要的 - 假设dat = mtcars- 但它不起作用:
foo(... = cyl)
错误:名称不得采用
...或形式..j。
我可以修改函数或调用以允许直接指定...吗?
以前,我曾经group_by_at按字符串向量或按 NULL 分组:
library(tidyverse)
grouping_1 <- c("cyl", "vs")
grouping_2 <- NULL
mtcars %>% group_by_at(grouping_1)
mtcars %>% group_by_at(grouping_2)
Run Code Online (Sandbox Code Playgroud)
的帮助group_by_at表明该函数已被取代,across应改为使用该函数。但是,按 NULL 分组会出现错误
mtcars %>% group_by(across(grouping_1)) # this works
mtcars %>% group_by(across(grouping_2)) # this gives an error
Run Code Online (Sandbox Code Playgroud)
对我来说,group_by_at以所描述的方式使用很有用,因为在我的函数中,我可以使用相同的代码,而无需每次都检查分组参数是否为空 (NULL)。