选择一个或多个行满足特定条件的组

时间:2018-12-29 06:15:21

标签: r dplyr

我正在使用tidyverse包清除R中的数据。我想选择一个或多个行符合特定条件的所有组。

我有一个类似于以下数据:

require(tidyverse)
dat <- data_frame(
  group = rep(c("A", "B", "C"),3),
  key = c(1,1,0, 0,0,0,1,0,0),
  value = rnorm(n= 9, mean = 3, sd = 1)
)

#A tibble: 9 x 3
#Groups:   group [3]
  group   key value
  <chr> <dbl> <dbl>
1 A         1  3.97
2 B         1  2.05
3 C         0  3.28
4 A         0  4.22
5 B         0  2.67
6 C         0  5.02
7 A         1  2.60
8 B         0  3.99
9 C         0  4.42

对于此示例,我想选择一个或多个键等于1的组。只有组A和B包含键为1的行。因此,我的预期结果将是:

#A tibble: 9 x 3
#Groups:   group [3]
  group   key value
  <chr> <dbl> <dbl>
1 A         1  3.97
2 B         1  2.05
4 A         0  4.22
5 B         0  2.67
7 A         1  2.60
8 B         0  3.99

3 个答案:

答案 0 :(得分:2)

相对简单的解决方案如下:

library(dplyr)

set.seed(12345)

dat <- data_frame(
  group = rep(c("A", "B", "C"),3),
  key = c(1,1,0, 0,0,0,1,0,0),
  value = rnorm(n= 9, mean = 3, sd = 1)
)

dat %>% 
  group_by(group) %>% 
  filter(sum(key == 1) > 0)

#> # A tibble: 6 x 3
#> # Groups:   group [2]
#>   group   key value
#>   <chr> <dbl> <dbl>
#> 1 A         1  3.59
#> 2 B         1  3.71
#> 3 A         0  2.55
#> 4 B         0  3.61
#> 5 A         1  3.63
#> 6 B         0  2.72

一旦按变量分组,就可以应用过滤器,请记住,任何调用该变量的函数都将应用于该变量的向量,该向量仅属于该组。

答案 1 :(得分:1)

使用ave的基本R选项为

dat[with(dat, ave(key == 1, group, FUN = function(x) any(sum(x) > 0))), ]

# group   key value
#  <chr> <dbl> <dbl>
#1 A        1. 0.875
#2 B        1. 2.61 
#3 A        0. 3.30 
#4 B        0. 1.40 
#5 A        1. 4.52 
#6 B        0. 3.34 

答案 2 :(得分:1)

这里有一些选择。

1)使用data.table

library(data.table)
setDT(dat)[dat[, .I[sum(key == 1) > 0], group]$V1]
#    group key value
#1:     A   1  3.97
#2:     A   0  4.22
#3:     A   1  2.60
#4:     B   1  2.05
#5:     B   0  2.67
#6:     B   0  3.99

2)base R

a)以紧凑的方式与ave

dat[!!with(dat, ave(key, group, FUN = max)), ]

b)使用table

subset(dat, group %in% names(which(!!table(dat[1:2])[,2])))

c)使用rowsum

subset(dat, group %in% names(which((rowsum(key, group) > 0) [, 1])))

3)使用tidyverse

library(tidyverse)
dat %>%  
    group_by(group) %>%
    filter(sum(key) > 0)

数据

dat <- structure(list(group = c("A", "B", "C", "A", "B", "C", "A", "B", 
"C"), key = c(1L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L), value = c(3.97, 
2.05, 3.28, 4.22, 2.67, 5.02, 2.6, 3.99, 4.42)), class = "data.frame", 
 row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9"))