rlang - 获取作为字符串传递的对象的 class,而不是字符串本身或现状
rlang - get the class of an object passed as a string, rather than the string itself or the quo
我试图通过传递列名称的字符串来获取 tibble 中列的 classes。像往常一样,rlang 的文档是如此难以辨认,以至于我无法弄清楚如何使字符串被评估为实际对象,并且我已经尝试 return class of "quosure" 或 "name".
require(tidyverse)
#> Loading required package: tidyverse
suppressPackageStartupMessages(library(rlang))
(colstable <- mtcars %>% names %>% enframe(name = NULL, value = "column"))
#> # A tibble: 11 x 1
#> column
#> <chr>
#> 1 mpg
#> 2 cyl
#> 3 disp
#> 4 hp
#> 5 drat
#> 6 wt
#> 7 qsec
#> 8 vs
#> 9 am
#> 10 gear
#> 11 carb
colstable %>%
mutate(colclass = class(sym(paste0("mtcars$", column))))
#> Error: Only strings can be converted to symbols
#This crashes Rstudio immediately:
#colstable %>%
#mutate(colclass = class(quo(paste0("mtcars$", column))))
class(sym("mtcars$mpg"))
#> [1] "name"
class(quo("mtcars$mpg"))
#> [1] "quosure" "formula"
#Desired output would be the classes as produced by str()
str(mtcars)
#> 'data.frame': 32 obs. of 11 variables:
#> $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
#> $ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
#> $ disp: num 160 160 108 258 360 ...
#> $ hp : num 110 110 93 110 175 105 245 62 95 123 ...
#> $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
#> $ wt : num 2.62 2.88 2.32 3.21 3.44 ...
#> $ qsec: num 16.5 17 18.6 19.4 17 ...
#> $ vs : num 0 0 1 1 0 1 0 1 1 1 ...
#> $ am : num 1 1 1 0 0 0 0 0 0 0 ...
#> $ gear: num 4 4 4 3 3 3 3 4 4 4 ...
#> $ carb: num 4 4 1 1 2 1 4 2 2 4 ...
#Ie, all the values of "colclass" should be "num"
由 reprex package (v0.3.0)
于 2020-04-15 创建
发生错误是因为 sym
仅适用于单个元素。在这里,我们需要 syms
(但这不是获得预期输出的路线)。带有变量名的 $
将按字面意思计算它,因此请改用 [[
如果我们需要 class
,那么只需要
library(dplyr)
colstable %>%
rowwise %>%
mutate(colclass = class(mtcars[[column]]) )
# A tibble: 11 x 2
# Rowwise:
# column colclass
# <chr> <chr>
# 1 mpg numeric
# 2 cyl numeric
# 3 disp numeric
# 4 hp numeric
# 5 drat numeric
# 6 wt numeric
# 7 qsec numeric
# 8 vs numeric
# 9 am numeric
#10 gear numeric
#11 carb numeric
或 map
library(purrr)
colstable %>%
mutate(colclass = map_chr(column ~ class(mtcars[[.x]])))
或者如果我们需要eval
计算表达式
library(stringr)
colstable %>%
mutate(colclass = map_chr(rlang::parse_exprs(str_c("mtcars$", column, collapse=";")),
~ class(rlang::eval_tidy(.x))))
# A tibble: 11 x 2
# column colclass
# <chr> <chr>
# 1 mpg numeric
# 2 cyl numeric
# 3 disp numeric
# 4 hp numeric
# 5 drat numeric
# 6 wt numeric
# 7 qsec numeric
# 8 vs numeric
# 9 am numeric
#10 gear numeric
#11 carb numeric
这里真的没有必要 rlang
或任何非标准评估。
我们可以使用 map
获取 class 列,并获取长格式数据。
library(tidyverse)
map_df(mtcars, class) %>% pivot_longer(cols = everything())
# column class
# <chr> <chr>
# 1 mpg numeric
# 2 cyl numeric
# 3 disp numeric
# 4 hp numeric
# 5 drat numeric
# 6 wt numeric
# 7 qsec numeric
# 8 vs numeric
# 9 am numeric
#10 gear numeric
#11 carb numeric
如果只有我们感兴趣的特定列,我们可以在获取它们 class
之前 select
它们。
如果您必须使用 colstable
,我们可以 pull
数据框中的列并获取其 class。
colstable %>% mutate(class = map_chr(column, ~mtcars %>% pull(.x) %>% class))
我试图通过传递列名称的字符串来获取 tibble 中列的 classes。像往常一样,rlang 的文档是如此难以辨认,以至于我无法弄清楚如何使字符串被评估为实际对象,并且我已经尝试 return class of "quosure" 或 "name".
require(tidyverse)
#> Loading required package: tidyverse
suppressPackageStartupMessages(library(rlang))
(colstable <- mtcars %>% names %>% enframe(name = NULL, value = "column"))
#> # A tibble: 11 x 1
#> column
#> <chr>
#> 1 mpg
#> 2 cyl
#> 3 disp
#> 4 hp
#> 5 drat
#> 6 wt
#> 7 qsec
#> 8 vs
#> 9 am
#> 10 gear
#> 11 carb
colstable %>%
mutate(colclass = class(sym(paste0("mtcars$", column))))
#> Error: Only strings can be converted to symbols
#This crashes Rstudio immediately:
#colstable %>%
#mutate(colclass = class(quo(paste0("mtcars$", column))))
class(sym("mtcars$mpg"))
#> [1] "name"
class(quo("mtcars$mpg"))
#> [1] "quosure" "formula"
#Desired output would be the classes as produced by str()
str(mtcars)
#> 'data.frame': 32 obs. of 11 variables:
#> $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
#> $ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
#> $ disp: num 160 160 108 258 360 ...
#> $ hp : num 110 110 93 110 175 105 245 62 95 123 ...
#> $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
#> $ wt : num 2.62 2.88 2.32 3.21 3.44 ...
#> $ qsec: num 16.5 17 18.6 19.4 17 ...
#> $ vs : num 0 0 1 1 0 1 0 1 1 1 ...
#> $ am : num 1 1 1 0 0 0 0 0 0 0 ...
#> $ gear: num 4 4 4 3 3 3 3 4 4 4 ...
#> $ carb: num 4 4 1 1 2 1 4 2 2 4 ...
#Ie, all the values of "colclass" should be "num"
由 reprex package (v0.3.0)
于 2020-04-15 创建发生错误是因为 sym
仅适用于单个元素。在这里,我们需要 syms
(但这不是获得预期输出的路线)。带有变量名的 $
将按字面意思计算它,因此请改用 [[
如果我们需要 class
,那么只需要
library(dplyr)
colstable %>%
rowwise %>%
mutate(colclass = class(mtcars[[column]]) )
# A tibble: 11 x 2
# Rowwise:
# column colclass
# <chr> <chr>
# 1 mpg numeric
# 2 cyl numeric
# 3 disp numeric
# 4 hp numeric
# 5 drat numeric
# 6 wt numeric
# 7 qsec numeric
# 8 vs numeric
# 9 am numeric
#10 gear numeric
#11 carb numeric
或 map
library(purrr)
colstable %>%
mutate(colclass = map_chr(column ~ class(mtcars[[.x]])))
或者如果我们需要eval
计算表达式
library(stringr)
colstable %>%
mutate(colclass = map_chr(rlang::parse_exprs(str_c("mtcars$", column, collapse=";")),
~ class(rlang::eval_tidy(.x))))
# A tibble: 11 x 2
# column colclass
# <chr> <chr>
# 1 mpg numeric
# 2 cyl numeric
# 3 disp numeric
# 4 hp numeric
# 5 drat numeric
# 6 wt numeric
# 7 qsec numeric
# 8 vs numeric
# 9 am numeric
#10 gear numeric
#11 carb numeric
这里真的没有必要 rlang
或任何非标准评估。
我们可以使用 map
获取 class 列,并获取长格式数据。
library(tidyverse)
map_df(mtcars, class) %>% pivot_longer(cols = everything())
# column class
# <chr> <chr>
# 1 mpg numeric
# 2 cyl numeric
# 3 disp numeric
# 4 hp numeric
# 5 drat numeric
# 6 wt numeric
# 7 qsec numeric
# 8 vs numeric
# 9 am numeric
#10 gear numeric
#11 carb numeric
如果只有我们感兴趣的特定列,我们可以在获取它们 class
之前 select
它们。
如果您必须使用 colstable
,我们可以 pull
数据框中的列并获取其 class。
colstable %>% mutate(class = map_chr(column, ~mtcars %>% pull(.x) %>% class))