which.max无法正常运行

时间:2020-03-17 18:26:25

标签: r

我试图按组创建一个表,其中包含当x等于或小于某个值时的y值。下面是我使用虹膜数据集的代码。

对于“ <= 2.5”,我希望virginica组得到4.5、5.0或5.8,因为这些是与virginica的Sepal.Width关联的Petal.Length值2.5。但是,我得到了6.0。关于我哪里出了错的任何想法? (对于同一组,我的实际数据集没有类似于Sepal.Width的变量重复项,因此对我来说,在这些变量中进行选择不是问题。)

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])])  

这与问题Create a table with values from ecdf graph

有关

3 个答案:

答案 0 :(得分:4)

问题是您子集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无关。

答案 1 :(得分:3)

使用双循环使其更具扩展性:

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 :(得分:2)

这是获取相同数据的另一种方法。根据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