Выбор групп, в которых одна или несколько строк соответствуют определенным критериям - PullRequest
0 голосов
/ 29 декабря 2018

Я очищаю данные в R, используя пакет tidyverse.Я хотел бы выбрать все группы, в которых одна или несколько строк соответствуют определенному критерию.

У меня есть данные, которые выглядят следующим образом:

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 голосов
/ 29 декабря 2018

Базовая опция R с использованием ave будет

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 
0 голосов
/ 29 декабря 2018

Вот несколько вариантов.

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

а) компактным способом с 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)

data

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"))
0 голосов
/ 29 декабря 2018

Относительно простое решение выглядит следующим образом:

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

После группировки по переменной вы можете применить фильтр, помня, что любые функции, вызывающие переменную, будут применяться к вектору этой переменной, принадлежащейтолько для группы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...