将包含列名称和字段的data.frame作为过滤器传递

时间:2018-04-14 00:13:02

标签: r

假设我有以下内容:

filt = data.frame(X1 = c("Gender","EmployeeStatus"),X2 = c('Male','Active'))
df = data.frame(Gender = c('Male','F','Male','Male','F'),EmployeeStatus = c('Active','na','Active','Active','na'))

我希望能够将filt中的数据用作df的过滤器。我试过下面但是我得到了一个错误:第一个参数无效。

 d2 = df[get(filt[1,1])==filt[2,1] &
                  get(filt[1,2])==filt[2,2]]

3 个答案:

答案 0 :(得分:2)

您正在寻找的内容称为semi_join,您需要使用不同格式的过滤器数据框:

library(dplyr)
df <- data.frame(Gender = c('Male','F','Male','Male','F'),EmployeeStatus = c('Active','na','Active','Active','na'),stringsAsFactors = FALSE)
filt <- data.frame(Gender = "Male",EmployeeStatus = "Active",stringsAsFactors = FALSE)
> semi_join(df,filt)
Joining, by = c("Gender", "EmployeeStatus")
  Gender EmployeeStatus
1   Male         Active
2   Male         Active
3   Male         Active

(顺便说一句,我认为你在你的问题中转换了一些指数。)

答案 1 :(得分:1)

OP代码中存在许多问题。语法仅在data.table范围内有效:

library(data.table)
setDT(df)

d2 = df[get(as.character(filt[1,1]))==as.character(filt[1,2]) &
          get(as.character(filt[2,1]))==as.character(filt[2,2])]

#     Gender EmployeeStatus
# 1:   Male         Active
# 2:   Male         Active
# 3:   Male         Active

让我试着解释OP代码不起作用的原因。

get(filt[1,1]) => Gender. 

众所周知,df[Gender,]df["Gender",]data.frame的范围内不起作用。变量Genderdata.frame的范围内不可用。最重要的filt[1,1]类型factorget无法强制执行的as.character(filt[1,1])

因此,在上述解决方案中实施的变更可以描述为:

首先,factor会将character更改为df[get("Gender"),]。然后data.tablepage-structure.xsl范围内的有效语法。

答案 2 :(得分:1)

我们可以使用base R来执行此操作

df[Reduce(`&`, Map(`==`, df[as.character(filt$X1)], 
            as.character(filt$X2))),]
#   Gender EmployeeStatus
#1   Male         Active
#3   Male         Active
#4   Male         Active

rowSums

中的base R
df[rowSums(df[as.character(filt$X1)] == as.list(as.character(filt$X2))) == 2,]