使用dplyr的分割应用组合(split apply combine)技术,在使用slice函数后如何保留NA值。

6
mtcars %>% select(mpg, cyl) %>% group_by(cyl) %>% arrange(mpg) %>% slice(8)

输出

    mpg   cyl
  <dbl> <dbl>
1  30.4     4
2  15.2     8

如您所见,它没有为6个汽缸产生一行——保持所有组的推荐方法是什么,即使合并为空也是如此?


我不确定这是否理想,但是 mtcars %>% select(mpg, cyl) %>% group_by(cyl) %>% arrange(mpg) %>% summarise(mpg = mpg[8]) 是可行的。 - alistaire
好问题。似乎 slice 的设计与 R 中其他地方的 [] 表现不同。Alistaire 的解决方案还可以,直到你有更多列要处理时,此时你可能想切换到 data.table,使用类似 DT[order(mpg), .SD[8L], by=cyl, .SDcols="mpg"] 的语法... 好吧,我猜还有 summarise_each/summarise_at,但这些方法无法扩展到例如选择第七和第八行的情况。 - Frank
2
@Frank,你可以使用summarise_all轻松地进行泛化,例如:mtcars %>% select(mpg, cyl) %>% group_by(cyl) %>% arrange(mpg) %>% summarise_all(funs(.[8])) - alistaire
@alistaire 噢,好的,谢谢指点。我不知道summarise_all是一个功能。 - Frank
@alistaire,既然没有人给出答案,为什么不提出您的通用解决方案呢? - Sergey Aldoukhov
@SergeyAldoukhov 完成了。我还添加了一种选择多行的方式。 - alistaire
2个回答

3

为了快速选择每个组的一行,保留NA,你可以在summarise_all内部进行子集选择:

mtcars %>% group_by(cyl) %>% 
    arrange(mpg) %>% 
    summarise_all(funs(.[8]))

## # A tibble: 3 × 11
##     cyl   mpg  disp    hp  drat    wt  qsec    vs    am  gear  carb
##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1     4  30.4  75.7    52  4.93 1.615 18.52     1     1     4     2
## 2     6    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
## 3     8  15.2 304.0   150  3.15 3.435 17.30     0     0     3     2

然而,正如@Frank所说,在这种格式下,它不会很好地扩展到子集多行,因为summarise要求每个组一个单一的结果行。要对每个组的第7和8行进行子集操作,请使用列表列并使用tidyr :: unnest进行展开:

library(tidyverse)

mtcars %>% group_by(cyl) %>% 
    arrange(mpg) %>% 
    summarise_all(funs(list(.[7:8]))) %>% 
    unnest()

## # A tibble: 6 × 11
##     cyl   mpg  disp    hp  drat    wt  qsec    vs    am  gear  carb
##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1     4  27.3  79.0    66  4.08 1.935 18.90     1     1     4     1
## 2     4  30.4  75.7    52  4.93 1.615 18.52     1     1     4     2
## 3     6  21.4 258.0   110  3.08 3.215 19.44     1     0     3     1
## 4     6    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
## 5     8  15.2 275.8   180  3.07 3.780 18.00     0     0     3     3
## 6     8  15.2 304.0   150  3.15 3.435 17.30     0     0     3     2

使用purrr::dmap的更简洁版本返回相同的结果:

mtcars %>% group_by(cyl) %>% 
    arrange(mpg) %>% 
    dmap(~.x[7:8])

dmap has now moved to package purrrlyr - moodymudskipper

0

自从 dplyr 0.8 版本以后,我们可以使用 group_map 函数,因此像 @alistaire 一样,我们可以这样做:

library(dplyr)

mtcars2 <- mtcars %>% select(mpg, cyl) %>% group_by(cyl) %>% arrange(mpg)

mtcars2 %>% group_map(~.[8,]) 
#> # A tibble: 3 x 2
#> # Groups:   cyl [3]
#>     cyl   mpg
#>   <dbl> <dbl>
#> 1     4  30.4
#> 2     6  NA  
#> 3     8  15.2

mtcars2 %>% group_map(~.[7:8,]) 
#> # A tibble: 6 x 2
#> # Groups:   cyl [3]
#>     cyl   mpg
#>   <dbl> <dbl>
#> 1     4  27.3
#> 2     4  30.4
#> 3     6  21.4
#> 4     6  NA  
#> 5     8  15.2
#> 6     8  15.2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接