基于向量子集索引数据帧

时间:2012-11-29 00:37:59

标签: r dataframe subset

我有一个非常大的数据框,我想根据矢量的某个子集保存一个子集。总之,我有这样的事情:

> 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

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

3 个答案:

答案 0 :(得分:6)

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]

这通过DT的子集id,并返回.SD(子集的data.table)any(status=='flag')(在该子集内)。< / p>

答案 1 :(得分:2)

这似乎有效:

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

普通英语:从数据框中,选择id元素位于任何行标记状态的id元素向量中的每一行。

答案 2 :(得分: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