R:基于一列的两个条件的子集数据帧

时间:2018-07-25 10:20:59

标签: r

我有一个包含位置(loc)的数据框,其中每个位置都有两个区域(type)和每个区域中的干扰区域(area)。从我的数据框中,我想保留两个区域都发生干扰的位置。

我以为我可以通过按两个条件设置数据子集来简单地做到这一点,但是使用AND条件(&)

subset(dd, (dd$type == "npr" & dd$area > 0 ) & (dd$type == "buff" & dd$area > 0 ) ) 

为我提供空输出

[1] loc  type area
<0 rows> (or 0-length row.names)

并使用“或”条件(|)

subset(dd, (dd$type == "npr" & dd$area > 0 ) | (dd$type == "buff" & dd$area > 0 ) ) 

不是我想要的。

  loc type area
1   a  npr   10
2   a buff   20
4   b buff   10
5   c  npr    5
7   d  npr    5
8   d buff    5

如何正确区分两种区域类型中干扰区域均大于0的位置?


我的伪数据:

loc<-c("a", "a", "b", "b", "c", "c", "d", "d")
type= rep(c("npr", "buff"), 4)
area = c(10,20,0,10,5,0,5,5)


dd<-data.frame(loc, type, area)

所需的输出:

loc type area
1   a  npr   10
2   a buff   20
3   d  npr    5
4   d buff    5

2 个答案:

答案 0 :(得分:2)

您需要计算一个分组的摘要才能实现。也就是说,你想要 以找出每个loc在该位置的area all 是否大于0。 对于分组统计信息,我总是发现R有点尴尬,但这是 实现这一目标的一种方法。

首先,使用tapply()为每个loc确定是否应该 是否包含:

(include <- tapply(dd$area, dd$loc, function(x) all(x > 0)))
#>     a     b     c     d 
#>  TRUE FALSE FALSE  TRUE

然后,我们可以使用loc值对结果进行索引以获取合适的向量 用以下子集dd来组成子集:

include[dd$loc]
#>     a     a     b     b     c     c     d     d 
#>  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE

dd[include[dd$loc], ]
#>   loc type area
#> 1   a  npr   10
#> 2   a buff   20
#> 7   d  npr    5
#> 8   d buff    5

我们还可以将这些步骤放在subset()调用中,以避免 创建额外的变量:

subset(dd, tapply(area, loc, function(x) all(x > 0))[loc])
#>   loc type area
#> 1   a  npr   10
#> 2   a buff   20
#> 7   d  npr    5
#> 8   d buff    5

或者,您可以使用dplyr

library(dplyr)

dd %>% 
  group_by(loc) %>% 
  filter(all(area > 0))
#> # A tibble: 4 x 3
#> # Groups:   loc [2]
#>   loc   type   area
#>   <fct> <fct> <dbl>
#> 1 a     npr      10
#> 2 a     buff     20
#> 3 d     npr       5
#> 4 d     buff      5

reprex package(v0.2.0.9000)创建于2018-07-25。

答案 1 :(得分:2)

我将首先重塑:

loc<-c("a", "a", "b", "b", "c", "c", "d", "d")
type= rep(c("npr", "buff"), 4)
area = c(10,20,0,10,5,0,5,5)
dd<-data.frame(loc, type, area)

library(reshape2)
dd_wide <- dcast(dd, loc ~  type, value.var = "area")
mask <- subset(dd_wide, buff > 0 & npr > 0)[["loc"]]
subset(dd, loc %in% mask)

# one line:
subset(dd, loc %in% subset(dcast(dd, loc ~  type, value.var = "area"), buff > 0 & npr > 0)[["loc"]])