dplyr :: cume_dist () имеет разные результаты для сходных данных, это ошибка? - PullRequest
0 голосов
/ 17 июня 2019

Подобные данные дают разные результаты с функциями cume_dist () (и также процент_ранка ()) в dplyr.

[Редактировать: спасибо за комментарии. Гораздо проще демонстрация проблемы:]

library(tidyverse)
df <- tibble(a = runif(5), b = runif(5))
df[5, ] <- NA
df <- mutate(df, x = cume_dist(a - b), y = a - b)
out <- mutate(df, z = cume_dist(y))

Выходы:

> out
# A tibble: 5 x 5
       a       b     x       y     z
   <dbl>   <dbl> <dbl>   <dbl> <dbl>
1  0.154  0.427   0.25  -0.273   0.2
2  0.880  0.0455  0.75   0.835   0.6
3  0.989  0.0208  1      0.968   0.8
4  0.901  0.303   0.5    0.598   0.4
5 NA     NA      NA     NA      NA  

Почему столбцы x и z будут разными? Разве это не ошибка?

[Edit # 2: для потомков, вот лучшая демонстрация. Столбцы indirect и direct не должны быть разными.]

library(tidyverse)
set.seed(0)
df <- tibble(a = runif(1000, -1, 1), b = runif(1000, -1, 1))
df[df < 0] <- NA_real_  # or NA, doesn't matter
df <- df %>%
  mutate(gain = b - a)
df <- df %>%
  mutate(indirect = cume_dist(gain), 
         direct = cume_dist(b - a))
> sessionInfo()
R version 3.5.3 (2019-03-11)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.5

с версиями:

dplyr_0.8.1       
tidyverse_1.2.1     

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

Это ошибка.См. # 4427 для dplyr 0,8,2 вех.

0 голосов
/ 17 июня 2019

Это будет проблема с правильной NA отправкой.Здесь NA был создан путем присваивания только NA.и по умолчанию это будет NA_logical_.По какой-то причине cume_dist внутри mutate не распознает.Можно указать round или использовать as.integer, чтобы NA был преобразован в правильный NA

new_df %>% 
  mutate(gain = round(gain), cume_dist = cume_dist(gain))
# A tibble: 6 x 2
#   gain cume_dist
#  <dbl>     <dbl>
#1     0       0.6
#2    30       0.8
#3    36       1  
#4   -13       0.2
#5     0       0.6
#6    NA      NA  

или преобразован в integer

new_df %>% 
   mutate(gain = as.integer(gain), cume_dist = cume_dist(gain))

Проблема заключается в том, что NA не распознается в mutate.Если мы проверим функцию, cume_dist

cume_dist
#function (x) 
#{
#    rank(x, ties.method = "max", na.last = "keep")/sum(!is.na(x))
#}

Она берет rank и делит на количество не-NA элементов в этом столбце.Делая тот же код

new_df %>% 
     mutate(Cume_dist = rank(gain, ties.method = "max", 
            na.last = "keep")/sum(!is.na(gain)))
# A tibble: 6 x 2
#   gain Cume_dist
#  <dbl>     <dbl>
#1     0       0.6
#2    30       0.8
#3    36       1  
#4   -13       0.2
#5     0       0.6
#6    NA       NA

Если мы изменим знаменатель на количество строк в наборе данных

new_df %>% 
          mutate(Cume_dist = rank(gain, ties.method = "max", na.last = "keep")/n())
# A tibble: 6 x 2
#   gain Cume_dist
#  <dbl>     <dbl>
#1     0     0.5  
#2    30     0.667
#3    36     0.833
#4   -13     0.167
#5     0     0.5  
#6    NA    NA    

Это означает, что в пределах mutate env происходят некоторые измененияс элементом NA, взяв n() вместо 5 в знаменателе

Обратите внимание, что это не проблема вне mutate

cume_dist(new_df$gain)
#[1] 0.6 0.8 1.0 0.2 0.6  NA

Теперь, если мы изменимNA до NA_real_ (столбец двойной, и OP назначил NA без суффикса. Таким образом, по умолчанию это будет NA_logical_. Обычно это должно работать, но cume_dist может иметь некоторую ошибку дляправильно определить его внутри mutate).Давайте попробуем изменить NA на NA_real_

new_df$gain[is.na(new_df$gain)] <- NA_real_
new_df %>%
   mutate(Cume_dist = cume_dist(gain))
# A tibble: 6 x 2
#   gain Cume_dist
#  <dbl>     <dbl>
#1     0       0.6
#2    30       0.8
#3    36       1  
#4   -13       0.2
#5     0       0.6
#6    NA      NA  

data

df <- tibble(y = c(2, 3, 4, 1, 2, NA))
out1 <- mutate(df, 
  min_rank = min_rank(y),
  pct_rank = percent_rank(y),
  cume_dist = cume_dist(y)
)
flights_sml <- filter(flights, month == 3, day == 20)
r1 <- min(which(is.na(flights_sml$dep_delay)))
new_df <- flights_sml[c(9, (r1-4):r1), ]
new_df <- mutate(new_df,
  gain = dep_delay - arr_delay)
new_df <- select(new_df, gain)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...