【问题标题】:rlang - get the class of an object passed as a string, rather than the string itself or the quorlang - 获取作为字符串传递的对象的类,而不是字符串本身或 quo
【发布时间】:2020-04-15 23:01:22
【问题描述】:

我试图通过传递列名的字符串来获取 tibble 中的列类。像往常一样,rlang 的文档非常难以理解,以至于我无法弄清楚如何将字符串评估为实际对象,并且我所做的尝试返回了“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 创建

【问题讨论】:

    标签: r rlang


    【解决方案1】:

    发生错误是因为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]])))
    

    或者如果我们需要evaluate 表达式

    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 
    

    【讨论】:

    • 谢谢。这行得通,除了当我有一个有序因子(class() 返回向量长度 2)时,它会立即崩溃 R.require(tidyverse) colstable % names %>% enframe(name = NULL, value = "column") colstable %>% rowwise() %>% mutate(colclass= class(diamonds[[column]]))
    • @jzadra 在这种情况下,您可以更改代码以返回第一个,即colstable %&gt;% mutate(colclass = map_chr(rlang::parse_exprs(str_c("mtcars$", column, collapse=";")), ~ class(rlang::eval_tidy(.x))[1]))
    • @jzadra 或代替map_chr,只使用map,这样它就会返回list
    • @jzadra 如果你使用rowwise,则不需要map
    • @jzadra 我的意思是colstable %&gt;% mutate(colclass = map_chr(column, ~ class(diamonds[[.x]])[1]))
    【解决方案2】:

    这里真的不需要rlang 或任何非标准评估。

    我们可以使用map 获取列类并获取长格式数据。

    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
    

    如果只有我们感兴趣的特定列,我们可以先select 他们,然后再获得他们的class


    如果您必须使用colstable,我们可以pull 数据框中的列并获取其类。

    colstable %>% mutate(class = map_chr(column, ~mtcars %>% pull(.x) %>% class))
    

    【讨论】:

      猜你喜欢
      • 2018-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多