如何过滤具有两列条件的数据框? [复制]
Posted
技术标签:
【中文标题】如何过滤具有两列条件的数据框? [复制]【英文标题】:how to filter data frame with conditions of two columns? [duplicate] 【发布时间】:2013-12-03 18:26:04 【问题描述】:我正在尝试从数据框中进行选择。问题是为什么我下面的最后一个查询返回所有 5 条记录而不是前两条?
> x <- c(5,1,3,2,4)
> y <- c(1,5,3,4,2)
> data <- data.frame(x,y)
> data
x y
1 5 1
2 1 5
3 3 3
4 2 4
5 4 2
> data[data$x > 4 || data$y > 4]
x y
1 5 1
2 1 5
3 3 3
4 2 4
5 4 2
【问题讨论】:
尝试使用|
代替||
,然后查看help("||")
了解两者的区别。
【参考方案1】:
(1) 对于选择数据(子集),我强烈推荐 Hadley Wickhm 编写的 plyr
包中的 subset
函数,它更简洁易用:
library(plyr)
subset(data, x > 4 | y > 4)
更新:
plyr
有一个更新版本,称为 dplyr
(here),它也来自 Hadley,但据说更快更容易使用。如果你见过像%.%
或%>%
这样的操作符,你就会知道他们使用dplyr
链接操作。
result <- data %>%
filter(x>4 | y>4) #NOTE filter(condition1, condition2..) for AND operators.
(2)|
和||
确实存在一些差异:
您可以通过以下方式查看帮助手册:?'|'
较短的形式执行元素比较的方式与算术运算符大致相同。较长的形式从左到右评估,仅检查每个向量的第一个元素。仅在确定结果之前进行评估。较长的形式适用于编程控制流,通常在 if 子句中首选。
> c(1,1,0) | c(0,0,0)
[1] TRUE TRUE FALSE
> c(1,1,0) || c(0,0,0)
[1] TRUE
根据您的问题,您所做的基本上是data[TRUE]
,它...将返回完整的数据框。
【讨论】:
你确定subset
来自plyr
吗?
@DavidArenburg,我认为 R 的名称空间有时会令人困惑,我非常有信心 dplyr 中有一个子集函数,可能是 plyr,并且可能还有一个来自基本包的子集函数。 .
在 plyr 或 dplyr 中都没有 subset
函数。有data.table
的方法,但如果那让你感到困惑。
@DavidArenburg,除了你说的; subset
建议只用于交互使用;建议使用[
、[[
子集。因此,subset
可能也不适合这里,因为它无法在过滤时正确处理数据框中的NA
s。
编辑:虽然subset
建议仅用于交互使用,[
,[[
子集建议;上述解决方案对于数据框中存在NA
s 是稳健的:vc <- data.frame(duzey=factor(c("Y","O","Y","D","Y","Y","O"), levels=c("D","O","Y"), ordered=TRUE), cinsiyet=c("E","E","K",NA,"K","E","K"), yas=c(8,3,9,NA,7,NA,6), Not=c(NA,1,1,NA,NA,2,1)); vc; subset(vc, cinsiyet=="E" | Not<4); subset(vc, cinsiyet=="E" & Not<2)
。因此,能够使用NA
s 处理数据帧,这个解决方案很好。【参考方案2】:
这里有一些对我有用的东西。
data[data[,1] > 4 | data[,2] > 4,1:2]
我不确定您的方法为什么不起作用,但我认为这是因为您没有告诉它何时不打印。看看help("[")
。
【讨论】:
此解决方案 - 同构等同于 3 票data[data$x > 4 | data$y > 4,]
解决方案 - 对数据框中 NA
s 的存在并不稳健:vc <- data.frame(duzey=factor(c("Y","O","Y","D","Y","Y","O"), levels=c("D","O","Y"), ordered=TRUE), cinsiyet=c("E","E","K",NA,"K","E","K"), yas=c(8,3,9,NA,7,NA,6), Not=c(NA,1,1,NA,NA,2,1)); vc; vc[vc[,2] == "E" | vc[,4] < 4,1:4]; vc[vc[,2] == "E" & vc[,4] < 2,1:4]
。【参考方案3】:
获取您的确切代码并稍作修改
> x <- c(5,1,3,2,4)
> y <- c(1,5,3,4,2)
> data <- data.frame(x,y)
> data[data$x > 4 | data$y > 4,]
x y
1 5 1
2 1 5
有两件重要的事情需要注意。一个是||已改为|,二是在最后一个方括号前多了一个逗号(,),这样可以让过滤器正常工作。
【讨论】:
此解决方案对于数据框中NA
s 的存在并不稳健:vc <- data.frame(duzey=factor(c("Y","O","Y","D","Y","Y","O"), levels=c("D","O","Y"), ordered=TRUE), cinsiyet=c("E","E","K",NA,"K","E","K"), yas=c(8,3,9,NA,7,NA,6), Not=c(NA,1,1,NA,NA,2,1)); vc; vc[vc$cinsiyet == "E" | vc$Not < 4,]; vc[vc$cinsiyet == "E" & vc$Not < 2,]
以上是关于如何过滤具有两列条件的数据框? [复制]的主要内容,如果未能解决你的问题,请参考以下文章