как получить процентили, используя mutate_at? - PullRequest
0 голосов
/ 09 января 2019

Рассмотрим этот простой пример

> tibble(var1 = c(1,2,3,4,5),
+        boo1 = c(1,2,3,4,5))
# A tibble: 5 x 2
   var1  boo1
  <dbl> <dbl>
1     1     1
2     2     2
3     3     3
4     4     4
5     5     5

Здесь я хочу получить текущее значение, выраженное в процентах, используя ecdf. Ожидается, что это будет работать, но это не так.

> tibble(var1 = c(1,2,3,4,5),
+        boo1 = c(1,2,3,4,5)) %>% 
+   mutate_at(vars(contains('boo')), 
+             .funs = funs(ecdf(.)(.)))
Error in mutate_impl(.data, dots) : 
  Evaluation error: 'x' and 'y' lengths differ.

Вместо этого это работает

> tibble(var1 = c(1,2,3,4,5),
+        boo1 = c(1,2,3,4,5)) %>% mutate(percentile = ecdf(boo1)(boo1))
# A tibble: 5 x 3
   var1  boo1 percentile
  <dbl> <dbl>      <dbl>
1     1     1        0.2
2     2     2        0.4
3     3     3        0.6
4     4     4        0.8
5     5     5        1  

В чем здесь проблема? Спасибо!

1 Ответ

0 голосов
/ 09 января 2019

Две альтернативы будут

ecdfEval <- function(x) ecdf(x)(x)
tbl %>% mutate_at(vars(contains('boo')), ecdfEval)
# A tibble: 5 x 2
#    var1  boo1
#   <dbl> <dbl>
# 1     1   0.2
# 2     2   0.4
# 3     3   0.6
# 4     4   0.8
# 5     5   1

и

tbl %>% mutate_at(vars(contains('boo')), funs(do.call(ecdf(.), list(.))))
# A tibble: 5 x 2
#    var1  boo1
#   <dbl> <dbl>
# 1     1   0.2
# 2     2   0.4
# 3     3   0.6
# 4     4   0.8
# 5     5   1

Действительно странно, что ваш подход не сработал, похоже, что использование . во вложенных функциях является проблемой.


Редактировать (лучший вариант): кажется, что это может быть больше о funs, чем mutate_at, поскольку, как заметил @Nate, мы действительно можем использовать просто

tbl %>% mutate_at(vars(contains('boo')), .funs = ~ecdf(.)(.))

(См. Комментарий @ Нейта ниже для более подробной информации.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...