我正在使用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
答案 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"))