根据多个变量的条件值在R data.table中设置行

时间:2018-06-13 22:44:19

标签: r data.table subset

我感兴趣的是仅针对两个特定变量具有相同值的行的子集进行计算,而对另一个变量使用两个不同的值。

对于这个玩具数据集:

library(data.table)
DT = data.table(x = c(1,1,1,1,2,2,2,2,3,3,3,4,4,4,4,5,5,5,5,5), 
            y = c(10,10,10,10,24,24,26,26,51,51,51,34,34,34,34,65,65,65,65,65),
            z = c('m', 'm', 'f', 'f', 'b', 'b', 'm', 'm', 'b', 'b', 'b', 
            'm', 'm', 'f', 'f', 'b', 'b', 'b', 'b', 'b'))

我只对给定x值和y值的行感兴趣,z等于' m'并且' f'。所以在这个表中,我需要一个脚本来提取x = 1和x = 4的行,因为这些是y保持不变的唯一行,并且z同时具有' f'和' m'值。如果z有' b'价值,或只是' f'或者' m,我不需要它。

2 个答案:

答案 0 :(得分:3)

这主要是检查所有zm/fm/f是否都在z中表示。所以:

DT[, if(all(z %in% c("m","f")) & all(c("m","f") %in% z)) .SD,  by=.(x,y)]

正如@Frank在评论中明智地建议的那样,这是setequal,所以:

DT[, if(setequal(z, c("m","f"))) .SD,  by=.(x,y)]

#   x  y z
#1: 1 10 m
#2: 1 10 m
#3: 1 10 f
#4: 1 10 f
#5: 4 34 m
#6: 4 34 m
#7: 4 34 f
#8: 4 34 f

答案 1 :(得分:1)

因为您正在查看y是否未更改且该z包含mf,我们将使用all(c("m","f")%in%z)来查看z是否包含m和f并使用table(y)==.Nlength(unique(y))==1表示y没有变化。然后将其合并回数据,然后合并

DT[DT,s := table(y)==.N & all(z %in% c("m","f")),on = "x",by = .EACHI][s==T][,s := NULL][]
   x  y z
1: 1 10 m
2: 1 10 m
3: 1 10 f
4: 1 10 f
5: 4 34 m
6: 4 34 m
7: 4 34 f
8: 4 34 f

用于tidyverse格式:

DT%>%
   group_by(x)%>%
    filter(length(unique(y)) == 1 & all(z %in% c("m","f")))
# A tibble: 8 x 3
# Groups:   x [2]
      x     y z    
  <dbl> <dbl> <chr>
1    1.   10. m    
2    1.   10. m    
3    1.   10. f    
4    1.   10. f    
5    4.   34. m    
6    4.   34. m    
7    4.   34. f    
8    4.   34. f