从列表组合中的数据框中选择行 [英] Selecting rows from a data frame from combinations of lists

查看:32
本文介绍了从列表组合中的数据框中选择行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据框,数据:

I have a dataframe, dat:

dat<-data.frame(col1=rep(1:4,3),
                col2=rep(letters[24:26],4),
                col3=letters[1:12])

我想在两个不同的列上过滤 dat 仅使用数据框 filter 中的行给出的组合:

I want to filter dat on two different columns using ONLY the combinations given by the rows in the data frame filter:

filter<-data.frame(col1=1:3,col2=NA)
lists<-list(list("x","y"),list("y","z"),list("x","z"))
filter$col2<-lists

因此,例如,将选择包含 (1,x) 和 (1,y) 的行,但不会选择 (1,z)、(2,x) 或 (3,y).

So for example, rows containing (1,x) and (1,y), would be selected, but not (1,z),(2,x), or (3,y).

我知道如何使用 for 循环来做到这一点:

I know how I would do it using a for loop:

#create a frame to drop results in
results<-dat[1,]
for(f in 1:nrow(filter)){
  temp_filter<-filter[f,]
  temp_dat<-dat[dat$col1==temp_filter[1,1] &
                dat$col2%in%unlist(temp_filter[1,2]),]
  results<-rbind(results,temp_dat)
}

或者如果你更喜欢 dplyr 风格:

Or if you prefer dplyr style:

require(dplyr)
results<-dat[0,]
for(f in 1:nrow(filter)){
  temp_filter<-filter[f,]
  temp_dat<-filter(dat,col1==temp_filter[1,1] & 
  col2%in%unlist(temp_filter[1,2])
  results<-rbind(results,temp_dat)
}

结果应该返回

  col1 col2 col3
1    1    x    a
5    1    y    e
2    2    y    b
6    2    z    f
3    3    z    c
7    3    x    g

我通常会使用合并进行过滤,但我现在不能,因为我必须根据列表而不是单个值检查 col2.for 循环有效,但我认为有一种更有效的方法可以做到这一点,可能使用 applydo.call 的一些变体.

I would normally do the filtering using a merge, but I can't now since I have to check col2 against a list rather than a single value. The for loop works but I figured there would be a more efficient way to do this, probably using some variation of apply or do.call.

推荐答案

主要基于 dplyr 的一些帮助:

mostly base with a little help from dplyr:

dplyr::setdiff(dat,merge(dat,setNames(as.data.frame(filter),names(dat)[1:2])))

  col1 col2 col3
1    4    x    d
2    1    y    e
3    2    z    f
4    3    x    g
5    4    y    h
6    1    z    i
7    2    x    j
8    3    y    k
9    4    z    l

一个真正的基本 R 解决方案,虽然不是那么漂亮,但您会丢失行顺序:

A real base R solution though not so pretty and you lose the row order:

subset(merge(dat,`[[<-`(setNames(as.data.frame(filter),names(dat)[1:2]),"x",value=1),all.x=T),is.na(x),-4)

   col1 col2 col3
2     1    y    e
3     1    z    i
4     2    x    j
6     2    z    f
7     3    x    g
8     3    y    k
10    4    x    d
11    4    y    h
12    4    z    l

这篇关于从列表组合中的数据框中选择行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆