如果为真,在组和子集内的多列中搜索一个值。

问题描述 投票:0回答:1

我的目标是在组内进行分组,其中包括 cond==1 和其他条件 ==3 三次。所以,首先,我看 groupid. 接下来,我看一下 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 有资格进行子集,因为在同一行中,其中的 cond==1,其他条件至少取值3三次。另外,第2组为 id==500 也有 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 row subset
1个回答
2
投票

或者在 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

2
投票

下面是一个基本的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
© www.soinside.com 2019 - 2024. All rights reserved.