Использование contains () внутри функции mutate - PullRequest
2 голосов
/ 25 января 2020

Как можно сделать расчет, используя mutate и contains? Первое вычисление mutate дает ошибку:

Error: No tidyselect variables were registered
Run `rlang::last_error()` to see where the error occurred.
> rlang::last_error()
<error/rlang_error>
No tidyselect variables were registered
Backtrace:
  1. dplyr::mutate(., SomeCalc = contains("pal.Length")/contains(tal.Length))
 15. tidyselect::peek_vars()
 17. vars_env$selected %||% abort("No tidyselect variables were registered")
 18. dplyr::mutate(., SomeCalc = contains("pal.Length")/contains(tal.Length))
Run `rlang::last_trace()` to see the full context.
> rlang::last_trace()
<error/rlang_error>
No tidyselect variables were registered
Backtrace:
     █
  1. ├─iris %>% mutate(SomeCalc = contains("pal.Length")/contains(tal.Length))
  2. │ ├─base::withVisible(eval(quote(`_fseq`(`_lhs`)), env, env))
  3. │ └─base::eval(quote(`_fseq`(`_lhs`)), env, env)
  4. │   └─base::eval(quote(`_fseq`(`_lhs`)), env, env)
  5. │     └─`_fseq`(`_lhs`)
  6. │       └─magrittr::freduce(value, `_function_list`)
  7. │         ├─base::withVisible(function_list[[k]](value))
  8. │         └─function_list[[k]](value)
  9. │           ├─dplyr::mutate(., SomeCalc = contains("pal.Length")/contains(tal.Length))
 10. │           └─dplyr:::mutate.data.frame(., SomeCalc = contains("pal.Length")/contains(tal.Length))
 11. │             ├─base::as.data.frame(mutate(tbl_df(.data), ...))
 12. │             ├─dplyr::mutate(tbl_df(.data), ...)
 13. │             └─dplyr:::mutate.tbl_df(tbl_df(.data), ...)
 14. │               └─dplyr:::mutate_impl(.data, dots, caller_env())
 15. └─tidyselect::contains("pal.Length")
 16.   ├─base::tolower(vars)
 17.   └─tidyselect::peek_vars()
 18.     └─vars_env$selected %||% abort("No tidyselect variables were registered")

В то время как вторая функция mutate дает то, что я хочу, но я должен предоставить полное имя переменной. Как я могу предоставить только часть имени переменной?

Данные / код:

library(dplyr)
data(iris)
iris %>% 
  mutate(
    SomeCalc = contains("pal.Length") / contains(tal.Length)
  )


iris %>% 
  mutate(
    SomeCalc = Sepal.Length / Petal.Length
  )

РЕДАКТИРОВАТЬ:

SessionInfo()

> sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.3 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1

locale:
 [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8       
 [4] LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8   
 [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C          
[10] LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] dplyr_0.8.3

loaded via a namespace (and not attached):
 [1] tidyselect_0.2.5 compiler_3.6.1   magrittr_1.5     assertthat_0.2.1
 [5] R6_2.4.1         tools_3.6.1      pillar_1.4.2     glue_1.3.1      
 [9] rstudioapi_0.10  tibble_2.1.3     crayon_1.3.4     Rcpp_1.0.3      
[13] pkgconfig_2.0.3  rlang_0.4.2      purrr_0.3.3   

Ответы [ 2 ]

3 голосов
/ 25 января 2020

Вы также можете использовать mutate_at, что позволяет использовать операторы tidyselect:

mutate_at(vars(contains("pal.Length")), list(SomeCalc = ~. / Petal.Length ))

Пример:

library(dplyr)

data(iris)

ans2 <- iris %>% 
  mutate_at(vars(contains("pal.Length")),     list(SomeCalc = ~. / Petal.Length  ))

## compare result:
ans1 <- iris %>% 
  mutate(
    SomeCalc = Sepal.Length / Petal.Length
  )

all.equal(ans1, ans2)
#> [1] TRUE

Создано в 2020- 01-25 представьте пакет (v0.3.0)

3 голосов
/ 25 января 2020

Нам нужно передать строку в select (при условии, что соответствует только один столбец)

library(dplyr) # dev version 0.8.99.9000
iris %>% 
   mutate(
    SomeCalc = select(., contains("pal.Length")) / select(., contains("tal.Length"))
    )
#    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species Sepal.Length
#1            5.1         3.5          1.4         0.2     setosa     3.642857
#2            4.9         3.0          1.4         0.2     setosa     3.500000
#3            4.7         3.2          1.3         0.2     setosa     3.615385
#4            4.6         3.1          1.5         0.2     setosa     3.066667
#5            5.0         3.6          1.4         0.2     setosa     3.571429
#6            5.4         3.9          1.7         0.4     setosa     3.176471
#7            4.6         3.4          1.4         0.3     setosa     3.285714
#...

С помощью 0.8.3 dplyr мы можем извлечь набор данных как вектор а затем выполните деление

iris %>% 
  mutate(
    SomeCalc = select(., contains("pal.Length"))[[1]] / 
               select(., contains("tal.Length"))[[1]]
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...