【问题标题】:indexing a dataframe based on a vector subset基于向量子集索引数据帧
【发布时间】:2012-11-17 00:06:32
【问题描述】:

我有一个非常大的数据框,我想根据向量的某个子集保存其中的一个子集。简而言之,我有这样的事情:

> id<-c("ID1","ID2","ID2","ID3","ID4","ID4","ID4","ID4","ID4")
> status<-c("flag","flag","none","none","flag","flag","flag","none","flag")
> misc1ofmany<-c("etc1","etc2","etc3","etc4","etc5","etc6","etc7","etc8","etc9")
> df = data.frame(id, status, misc1ofmany) ; df
   id status misc1ofmany
1 ID1   flag        etc1
2 ID2   flag        etc2
3 ID2   none        etc3
4 ID3   none        etc4
5 ID4   flag        etc5
6 ID4   flag        etc6
7 ID4   flag        etc7
8 ID4   none        etc8
9 ID4   flag        etc9

我想要所有已标记的 ID 行,包括未标记的会话。现在我正在尝试通过 grep 获取其他 ID 的索引并将其插入新的 df 中。实际上,当我写这篇文章时,我发现 grepl 可能更容易使用:

> flaggedIDs <- unique(as.vector(df$id[grep("flag",df$status)]))
> flaggedIDs.allStats.Index <- mapply(grepl,df$id,MoreArgs=list(x=flaggedIDs)) 
> flaggedIDs.allStats.Index
      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9]
[1,]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[2,] FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
[3,] FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE

但是我只想到这里:

> flaggedIDsdf <- df[flaggedIDs.allStats.Index] ; flaggedIDsdf
   id status misc1ofmany
1 ID1   flag        etc1
2 ID2   flag        etc2
3 ID2   none        etc3
4 ID4   flag        etc5
5 ID4   flag        etc6
6 ID4   flag        etc7
7 ID4   none        etc8
8 ID4   flag        etc9

我觉得这应该比我想象的要简单,但是我尝试了多种可能性来解决这个问题,但无济于事。写出这个问题有助于这在我脑海中成为一个更清晰/更简单的问题(看起来我现在只是错过了一步),但现在我也想知道是否有更有效的方法来解决这个问题。

【问题讨论】:

    标签: r dataframe subset


    【解决方案1】:

    我相信你要做的事情可能会在一行中处理

    df[which(df$id %in% df$id[df$status=="flag"]), ]
    

    结果:

       id status misc1ofmany
    1 ID1   flag        etc1
    2 ID2   flag        etc2
    3 ID2   none        etc3
    5 ID4   flag        etc5
    6 ID4   flag        etc6
    7 ID4   flag        etc7
    8 ID4   none        etc8
    9 ID4   flag        etc9
    

    【讨论】:

    • 他似乎想保留 id 和 rows 只要它被标记。这只会保留那些被标记的。
    【解决方案2】:

    这似乎有效:

    df[df$id %in% df$id[df$status == "flag"],]
    

    简单的英语:从数据框中,选择id元素在任意行中状态被标记的id元素向量中的每一行。

    【讨论】:

      【解决方案3】:

      data.table 在这里非常有用,因为它优雅的语法和内存效率

      library(data.table)
      
      DT <- data.table(df)
      
      setkey(DT, 'id')
      
      DT[DT[status=='flag', list(id = unique(id))]]
      
          id status misc1ofmany
      1: ID1   flag        etc1
      2: ID2   flag        etc2
      3: ID2   none        etc3
      4: ID4   flag        etc5
      5: ID4   flag        etc6
      6: ID4   flag        etc7
      7: ID4   none        etc8
      8: ID4   flag        etc9
      

      甚至更紧凑

      DT[J(unique(id[status=='flag']))]
      

      上面这两种方法使用i 组件首先由data.table 评估的事实。 通过id 键入意味着我们可以进行自连接以仅提取ids 其中status=='flag 的那些。


      或者,使用by

      DT[,if(any(status=='flag')){.SD} ,by=id]
      

      这通过id 遍历DT 的子集,如果any(status=='flag')(在该子集内)返回.SD(子集的data.table)。

      【讨论】:

      • 非常优雅!谢谢你的回答!
      猜你喜欢
      • 1970-01-01
      • 2021-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多