which.max не работает должным образом - PullRequest
1 голос
/ 17 марта 2020

Я пытаюсь создать таблицу, которая включает в себя значение y, когда x равен или меньше определенного значения по группам. Ниже мой код с использованием набора данных радужной оболочки.

Для «<= 2,5» я ожидаю получить 4,5, 5,0 или 5,8 для группы virginica, поскольку это значения Petal.Length, связанные с Sepal.Width, равной 2,5 для virginica. Но вместо этого я получаю 6.0. Есть идеи, где я ошибся? (В моем фактическом наборе данных нет дубликатов переменной, аналогичной Sepal.Width для той же группы, поэтому выбор среди них не является для меня проблемой.) </p>

data(iris)

my.table <- iris %>%
  group_by(Species) %>%
  summarise("<=2.5" = Petal.Length[which.max(Sepal.Width[Sepal.Width<=2.5])],
            "<=3" = Petal.Length[which.max(Sepal.Width[Sepal.Width<=3])],
            "<=3.5" = Petal.Length[which.max(Sepal.Width[Sepal.Width<=3.5])],
            "<=4" = Petal.Length[which.max(Sepal.Width[Sepal.Width<=4])])  

Это связано с вопросом Создать таблицу со значениями из графика ecdf

Ответы [ 3 ]

4 голосов
/ 17 марта 2020

Проблема в том, что вы первый поднабор Sepal.Width. Следовательно, индекс, возвращаемый which.max, применяется к этому субвектору и больше не соответствует индексам всего Petal.Length вектора.

Чтобы исправить это, вам также необходимо соответственно задать подмножество Petal.Length Например,

…
`<=2.5` = Petal.Length[Sepal.Width <= 2.5][which.max(Sepal.Width[Sepal.Width <= 2.5])],
…

… конечно, это становится довольно многословным и повторяющимся. Может быть, лучше выполнить поднабор в отдельном шаге. Однако это означает создание новых столбцов для каждого порогового значения.

Кстати, это не связано с dplyr.

3 голосов
/ 17 марта 2020

Чтобы сделать его более масштабируемым, используйте двойной l oop:

myCuts <- c(2.5, 3, 3.5, 4)

res <- sapply(split(iris, iris$Species), function(i)
  sapply(myCuts, function(j){
    x <- i[ i$Sepal.Width <= j, ]
    x$Petal.Length[ which.max(x$Sepal.Width) ]
  }))

rownames(res) <- paste0("<=", myCuts)
res
#       setosa versicolor virginica
# <=2.5    1.3        3.9       4.5
# <=3      1.4        4.2       5.9
# <=3.5    1.4        4.5       5.6
# <=4      1.2        4.5       6.7
2 голосов
/ 17 марта 2020

Вот еще один способ получить те же данные. Создайте групповую переменную в соответствии со значениями Sepal.Width. Затем в каждой группе выберите строку с верхним значением Sepal.Width. Он имеет другую «форму», но вы всегда можете pivot_wider, если вы хотите, чтобы все значения были представлены в виде столбцов, а не строк.

iris %>%
  group_by(Species,
           Sepal.Width_grp = case_when(Sepal.Width <= 2.5 ~ '<=2.5',
                                       Sepal.Width <= 3 ~ '<=3',
                                       Sepal.Width <= 3.5 ~ '<=3.5',
                                       Sepal.Width <= 4 ~ '<=4',
                                       TRUE ~ '> 4')) %>%
  top_n(1, -Sepal.Width) %>% 
  select(Species, Sepal.Width_grp, Top.Sepal.Width = Sepal.Width, Petal.Width)
# # A tibble: 25 x 4
# # Groups:   Species, Sepal.Width_grp [12]
#    Species Sepal.Width_grp Top.Sepal.Width Petal.Width
#    <fct>   <chr>                     <dbl>       <dbl>
#  1 setosa  <=3.5                       3.1         0.2
#  2 setosa  <=4                         3.6         0.2
#  3 setosa  <=3                         2.9         0.2
#  4 setosa  <=3.5                       3.1         0.1
#  5 setosa  <=4                         3.6         0.2
#  6 setosa  <=3.5                       3.1         0.2
#  7 setosa  > 4                         4.1         0.1
#  8 setosa  <=3.5                       3.1         0.2
#  9 setosa  <=4                         3.6         0.1
# 10 setosa  <=2.5                       2.3         0.3
# # ... with 15 more rows

Редактировать: немного проще, если вы используете cut

iris %>%
  group_by(Species,
           Sepal.Width_grp = cut(Sepal.Width, c(0, 2.5, 3, 3.5, 4, Inf))) %>% 
  top_n(1, -Sepal.Width) %>% 
  select(Species, Sepal.Width_grp, Top.Sepal.Width = Sepal.Width, Petal.Width)
# # A tibble: 25 x 4
# # Groups:   Species, Sepal.Width_grp [12]
#    Species Sepal.Width_grp Top.Sepal.Width Petal.Width
#    <fct>   <fct>                     <dbl>       <dbl>
#  1 setosa  (3,3.5]                     3.1         0.2
#  2 setosa  (3.5,4]                     3.6         0.2
#  3 setosa  (2.5,3]                     2.9         0.2
#  4 setosa  (3,3.5]                     3.1         0.1
#  5 setosa  (3.5,4]                     3.6         0.2
#  6 setosa  (3,3.5]                     3.1         0.2
#  7 setosa  (4,Inf]                     4.1         0.1
#  8 setosa  (3,3.5]                     3.1         0.2
#  9 setosa  (3.5,4]                     3.6         0.1
# 10 setosa  (0,2.5]                     2.3         0.3
# # ... with 15 more rows
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...