dplyr: пользовательская функция в summarize_at

#r #dplyr #tidyverse

#r #dplyr #tidyverse

Вопрос:

Я хотел бы использовать свою собственную функцию smd в summarize_at , но безуспешно. Если я попытаюсь сделать:

 library(dplyr)

# My function
smd<-function(x,...)
  {sd(x)/sqrt(length(x)-1)}

starwars %>%
  summarise_at(c("height", "mass"), smd, na.rm = TRUE)

Erro: C stack usage  15924224 is too close to the limit

  

Не работает!! Попробуйте сделать funs(smd) так, чтобы и funs(sd/sqrt(n()-1)) и тоже не работали!

Пожалуйста, есть идеи?

Комментарии:

1. Ваш код отлично работает на моей машине, за исключением того, что он возвращает только NAs

2. Вы можете включить ... в sd функцию, и это исправит ошибку, но это также изменит длину, поэтому вам нужно учитывать это

Ответ №1:

Первое изменение заключается в том, чтобы перейти na.rm= к sd(.) , так что

 smd <- function(x, ...) sd(x, ...)/sqrt(length(x)-1)
starwars %>%
  summarise_at(c("height", "mass"), smd, na.rm=TRUE)
# # A tibble: 1 x 2
#   height  mass
#    <dbl> <dbl>
# 1   3.75  18.3
  

Однако, как предложил @astrofunkswag, вам нужно подумать, должны ли NA значения уменьшать вашу длину. Для этого нам нужно заменить length(x) на sum(!is.na(x)) .

 smd <- function(x, ...) sd(x, ...)/sqrt(sum(!is.na(x))-1)
starwars %>%
  summarise_at(c("height", "mass"), smd, na.rm=TRUE)
# # A tibble: 1 x 2
#   height  mass
#    <dbl> <dbl>
# 1   3.89  22.3
  

Комментарии:

1. Почему @r2evans, если я использую group_by in starwars%>% group_by(gender) %>% summarise_at(c("height", "mass"), smd, na.rm=TRUE) , не работает? Ошибка: проблема с summarise() вводом height . x неиспользуемый аргумент (na.rm = TRUE), который я ввожу height (function (x, ...) ... . i Ошибка произошла в группе 1: пол = «женский». Запустите rlang::last_error() , чтобы увидеть, где произошла ошибка.

Ответ №2:

Мы также можем сделать это с помощью summarise/across

 smd <- function(x, ...) sd(x, ...)/sqrt(sum(complete.cases(x))-1)
starwars %>%
     summarise(across(c(height, mass), smd, na.rm = TRUE))
  

-вывод

 # A tibble: 1 x 2
#  height  mass
#   <dbl> <dbl>
#1   3.89  22.3