rlang - получить класс объекта, переданного в виде строки, а не самой строки или кво - PullRequest
1 голос
/ 16 апреля 2020

Я пытаюсь получить классы столбцов в таблице, передавая строку имени столбца. Как обычно, документация по 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"

Создано в 2020-04-15 пакетом представ (v0.3.0)

Ответы [ 2 ]

2 голосов
/ 16 апреля 2020

Произошла ошибка, поскольку 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 
1 голос
/ 16 апреля 2020

Не вижу здесь необходимости 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

Если есть только определенные c столбцы, которые нас интересуют, мы можем select их, прежде чем получить их class.


Если вам нужно использовать colstable, мы можем pull столбец из кадра данных и получить его класс.

colstable %>% mutate(class = map_chr(column, ~mtcars %>% pull(.x) %>% class))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...