如果为真,则在组和子集中的多个列中搜索值
Searching a value in multiple columns within group and subset if true
我的目标是在组内对组进行子集,其中 cond==1
和其他条件 ==3
三次。所以,首先,我查看 id
内的 group
。接下来,我只看cond1==1
。如果cond1==1
,我统计有多少个条件取值3
。如果我看到三个条件取值 3
,那么我取整个 group
但在 id
.
之内
这是df
:
df = data.frame(id = c(rep(450, 4),rep(500, 4)),
group = c(rep(1, 2), rep(2,2)),
cond1 = c(1,2,1,2,1,2,2,1),
cond2 = c(1,3,3,1,3,2,3,1),
cond3 = c(3,3,1,2,3,1,2,3),
cond4 = c(3,2,2,3,3,1,2,3),
cond5 = c(3,2,3,3,3,1,2,3))
下面是 df
的样子:
id group cond1 cond2 cond3 cond4 cond5
1 450 1 1 1 3 3 3
2 450 1 2 3 3 2 2
3 450 2 1 3 1 2 3
4 450 2 2 1 2 3 3
5 500 1 1 3 3 3 3
6 500 1 2 2 1 1 1
7 500 2 2 3 2 2 2
8 500 2 1 1 3 3 3
例如,从该数据框中,id==450
的第 1 组有资格进行子集化,因为在同一行中,cond==1
,其他条件至少三次取值 3。此外,id==500
的第 2 组也有 cond==1
并且行中至少有三个值 3
。顺序无关紧要。
结果应该是这样的:
id group cond1 cond2 cond3 cond4 cond5
1 450 1 1 1 3 3 3
2 450 1 2 3 3 2 2
7 500 2 2 3 2 2 2
8 500 2 1 1 3 3 3
这是一个基本的 R 选项
r <- do.call(
rbind,
lapply(
split(df, df[c("id", "group")]),
function(v) subset(v, rowSums(v[-c(1:3)] == 3) >= 3)
)
)
dfout <- `row.names<-`(r[order(r$id,r$group),],NULL)
这样
> df
id group cond1 cond2 cond3 cond4 cond5
1 450 1 1 1 3 3 3
2 450 1 2 3 3 2 2
3 450 2 1 3 1 2 3
4 450 2 2 1 2 3 3
5 500 1 1 3 3 3 3
6 500 1 2 2 1 1 1
7 500 2 2 3 2 2 2
8 500 2 1 1 3 3 3
如果想保留原始数据框中的行号,可以试试
r <- Reduce(
rbind,
lapply(
split(df, df[c("id", "group")]),
function(v) subset(v, rowSums(v[-c(1:3)] == 3) >= 3)
)
)
dfout <- r[order(as.integer(rownames(r))), ]
这给出了
> dfout
id group cond1 cond2 cond3 cond4 cond5
1 450 1 1 1 3 3 3
3 450 2 1 3 3 2 3
5 500 1 1 3 3 3 3
8 500 2 1 1 3 3 3
或在dplyr
library(dplyr)
df %>%
mutate(ind = rowSums(select(., cond2:cond5) == 3) == 3) %>%
group_by(id, group) %>%
filter(if(any(ind & cond1 == 1)) all(ind[cond1==1]) else FALSE)%>%
ungroup %>%
select(-ind)
# A tibble: 4 x 7
# id group cond1 cond2 cond3 cond4 cond5
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 450 1 1 1 3 3 3
#2 450 1 2 3 3 2 2
#3 500 2 2 3 2 2 2
#4 500 2 1 1 3 3 3
我的目标是在组内对组进行子集,其中 cond==1
和其他条件 ==3
三次。所以,首先,我查看 id
内的 group
。接下来,我只看cond1==1
。如果cond1==1
,我统计有多少个条件取值3
。如果我看到三个条件取值 3
,那么我取整个 group
但在 id
.
这是df
:
df = data.frame(id = c(rep(450, 4),rep(500, 4)),
group = c(rep(1, 2), rep(2,2)),
cond1 = c(1,2,1,2,1,2,2,1),
cond2 = c(1,3,3,1,3,2,3,1),
cond3 = c(3,3,1,2,3,1,2,3),
cond4 = c(3,2,2,3,3,1,2,3),
cond5 = c(3,2,3,3,3,1,2,3))
下面是 df
的样子:
id group cond1 cond2 cond3 cond4 cond5
1 450 1 1 1 3 3 3
2 450 1 2 3 3 2 2
3 450 2 1 3 1 2 3
4 450 2 2 1 2 3 3
5 500 1 1 3 3 3 3
6 500 1 2 2 1 1 1
7 500 2 2 3 2 2 2
8 500 2 1 1 3 3 3
例如,从该数据框中,id==450
的第 1 组有资格进行子集化,因为在同一行中,cond==1
,其他条件至少三次取值 3。此外,id==500
的第 2 组也有 cond==1
并且行中至少有三个值 3
。顺序无关紧要。
结果应该是这样的:
id group cond1 cond2 cond3 cond4 cond5
1 450 1 1 1 3 3 3
2 450 1 2 3 3 2 2
7 500 2 2 3 2 2 2
8 500 2 1 1 3 3 3
这是一个基本的 R 选项
r <- do.call(
rbind,
lapply(
split(df, df[c("id", "group")]),
function(v) subset(v, rowSums(v[-c(1:3)] == 3) >= 3)
)
)
dfout <- `row.names<-`(r[order(r$id,r$group),],NULL)
这样
> df
id group cond1 cond2 cond3 cond4 cond5
1 450 1 1 1 3 3 3
2 450 1 2 3 3 2 2
3 450 2 1 3 1 2 3
4 450 2 2 1 2 3 3
5 500 1 1 3 3 3 3
6 500 1 2 2 1 1 1
7 500 2 2 3 2 2 2
8 500 2 1 1 3 3 3
如果想保留原始数据框中的行号,可以试试
r <- Reduce(
rbind,
lapply(
split(df, df[c("id", "group")]),
function(v) subset(v, rowSums(v[-c(1:3)] == 3) >= 3)
)
)
dfout <- r[order(as.integer(rownames(r))), ]
这给出了
> dfout
id group cond1 cond2 cond3 cond4 cond5
1 450 1 1 1 3 3 3
3 450 2 1 3 3 2 3
5 500 1 1 3 3 3 3
8 500 2 1 1 3 3 3
或在dplyr
library(dplyr)
df %>%
mutate(ind = rowSums(select(., cond2:cond5) == 3) == 3) %>%
group_by(id, group) %>%
filter(if(any(ind & cond1 == 1)) all(ind[cond1==1]) else FALSE)%>%
ungroup %>%
select(-ind)
# A tibble: 4 x 7
# id group cond1 cond2 cond3 cond4 cond5
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 450 1 1 1 3 3 3
#2 450 1 2 3 3 2 2
#3 500 2 2 3 2 2 2
#4 500 2 1 1 3 3 3