通过不同数量的逻辑列过滤数据帧

时间:2014-03-25 20:23:54

标签: r filter dataframe

我有一个问题我确信有一个我无法找到的优雅解决方案。

我有一个函数可以创建一个具有不同逻辑向量集的数据帧。在函数结束时,我想组合所有现有的逻辑向量。潜在的名称是已知的,但有足够的if语句的各种排列是不可行的。

例如,下面的两个数据表。潜在的逻辑向量是“夜晚”,“宠物”,“上升”,并且将存在1到3个。我想要能够可靠地组合存在的任何逻辑向量的代码。

我得到的列号列表与潜在列的名称相匹配,但无法将其带回家

希望这很清楚,谢谢你的帮助

df1 <- structure(list(hour = structure(c(1123624800, 1123628400, 1123632000, 
1123635600, 1123639200), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    night = c(FALSE, FALSE, TRUE, TRUE, TRUE), pet = c(TRUE, 
    TRUE, TRUE, TRUE, TRUE)), .Names = c("hour", "night", "pet"
), row.names = c(NA, 5L), class = "data.frame")

structure(list(hour = structure(c(1123624800, 1123628400, 1123632000, 
1123635600, 1123639200), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    night = c(FALSE, FALSE, TRUE, TRUE, TRUE), pet = c(TRUE, 
    TRUE, TRUE, TRUE, TRUE), rising = c(TRUE, TRUE, FALSE, TRUE, 
    FALSE)), .Names = c("hour", "night", "pet", "rising"), row.names = c(NA, 
5L), class = "data.frame")


filters <- c("rising", "pet", "night")
match(filters, names(df))[!is.na(match(filters, names(df)))]

如果我明确写出我想要代码的内容:

return(df1[df1$night & df1$pet, ]) 
return(df2[df2$night & df2$pet $ df2$rising, ])
编辑:我打算重写一下,希望更清楚。 我有一个包含多达三个逻辑向量的数据帧,其中包含各种数据质量过滤器的标志。例如,三个潜在载体的名称是“夜晚”,“宠物”,“上升”。数据帧将具有1到3个这些向量的某种组合。有时它会有“宠物”和“夜晚”,或“夜晚”和“上升”,或“宠物”和“上升”,或全部三个......

我想返回所有现有逻辑向量为true的记录。问题是我事先不知道哪些向量存在(这取决于函数调用中的选项),所以我想编写代码以便能够处理所有各种组合。类似的东西:

check which logical vectors exist
return(df[(all existing vectors are true), ]

如果我尝试

return(df[df$rising & df$pet $ df$night, ]) 

只要缺少其中一列,代码就会失败,所以我需要一种更强大的方法来实现这一目标。

希望这更清楚!一般来说,如果我无法表达问题,那就意味着我做了一些愚蠢的事......

1 个答案:

答案 0 :(得分:2)

更新:

df2[Reduce(`&`, df2[sapply(df2, is.logical)]),]

将返回所有逻辑列为TRUE的行。您还可以使用最后描述的apply方法。


您可以使用Reduce&

实现目标
df1[Reduce(`&`, df1[-1]),]
#                  hour night  pet
# 3 2005-08-10 00:00:00  TRUE TRUE
# 4 2005-08-10 01:00:00  TRUE TRUE
# 5 2005-08-10 02:00:00  TRUE TRUE

上面我们用-1排除了第一列。下面我们使用您在filters中定义的列列表:

df2[Reduce(`&`, df2[filters]),]
#                  hour night  pet rising
# 4 2005-08-10 01:00:00  TRUE TRUE   TRUE 

Reduce迭代地将&应用于第二个参数中的元素对(数据框中的列)。

或者,您可以使用apply

df2[apply(df2[filters], 1, all),]
df1[apply(df1[-1], 1, all),]