代码之家  ›  专栏  ›  技术社区  ›  maycca

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

r
  •  2
  • maycca  · 技术社区  · 7 年前

    我有一个包含位置的数据框( loc ,每个位置有两个区域( type )以及每个区域的干扰区域( area )从我的数据框架中,我想保留在两个区域都有干扰的位置。

    我想我可以通过按两个条件子集数据来实现这一点,但是使用和条件(&)

    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 回复  |  直到 7 年前
        1
  •  2
  •   Mikko Marttila    7 年前

    您需要计算一个分组摘要来实现这一点。也就是说,你想要 找出每个 loc 如果 全部的 area 在该位置的是>0。 我一直觉得R基对分组统计有点笨拙,但这里有 实现这一目标的一种方法。

    首先,使用 tapply() 确定每个 洛克 是否应该 是否包括:

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

    然后我们可以使用 洛克 索引结果以获得适合的向量的值 子集 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
    

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

        2
  •  2
  •   r.user.05apr    7 年前

    我会先整形:

    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"]])