我想通过指定要保留在新数据帧中的不(!
)行来对数据帧进行子集化(过滤)。以下是简化的示例数据框:
data
v1 v2 v3 v4
a v d c
a v d d
b n p g
b d d h
c k d c
c r p g
d v d x
d v d c
e v d b
e v d c
例如,如果列v1的行有“b”,“d”或“e”,我想摆脱那一行观察,产生以下数据帧:
v1 v2 v3 v4
a v d c
a v d d
c k d c
c r p g
我一次成功完成基于一个条件的子集化。例如,在这里我删除v1包含“b”的行:
sub.data <- data[data[ , 1] != "b", ]
然而,我有很多这样的条件,所以一次做一个是不可取的。我没有成功完成以下任务:
sub.data <- data[data[ , 1] != c("b", "d", "e")
或
sub.data <- subset(data, data[ , 1] != c("b", "d", "e"))
我也试过了其他一些事情,比如!%in%
,但这似乎并不存在。
有什么想法吗?
答案 0 :(得分:46)
试试这个
subset(data, !(v1 %in% c("b","d","e")))
答案 1 :(得分:39)
!
应该在声明的外部:
data[!(data$v1 %in% c("b", "d", "e")), ]
v1 v2 v3 v4
1 a v d c
2 a v d d
5 c k d c
6 c r p g
答案 2 :(得分:10)
您还可以通过包含&
来分隔语句,将事情分解为单独的逻辑语句来实现此目的。
subset(my.df, my.df$v1 != "b" & my.df$v1 != "d" & my.df$v1 != "e")
这不优雅,需要更多代码,但对于较新的R用户可能更具可读性。正如上面的评论所指出的,subset
是一种“便利”功能,最适合在交互式工作时使用。
答案 3 :(得分:5)
data <- data[-which(data[,1] %in% c("b","d","e")),]
答案 4 :(得分:4)
这个答案更多的是解释原因,而不是如何解释。 R中的'=='
运算符的矢量化方式与'+'
运算符相同。它将左侧任何元素与每个元素右侧元素的元素相匹配。例如:
> 1:3 == 1:3
[1] TRUE TRUE TRUE
此处第一个测试是1==1
,它是TRUE,第二个2==2
和第三个3==3
。请注意,这会在第一个和第二个元素中返回FALSE,因为顺序错误:
> 3:1 == 1:3
[1] FALSE TRUE FALSE
现在,如果一个对象小于另一个对象,那么较小的对象将重复与匹配较大对象所需的一样多。如果较大对象的大小不是较小对象大小的倍数,则会收到警告,并非所有元素都重复出现。例如:
> 1:2 == 1:3
[1] TRUE TRUE FALSE
Warning message:
In 1:2 == 1:3 :
longer object length is not a multiple of shorter object length
这里的第一个匹配是1==1
,然后是2==2
,最后是1==3
(FALSE)因为左侧较小。如果其中一个边只是一个元素,那么重复:
> 1:3 == 1
[1] TRUE FALSE FALSE
测试元素是否在向量中的正确运算符确实是'%in%'
,它仅向左矢量化(对于左向量中的每个元素,如果它是其中任何对象的一部分,则对其进行测试)正确的元素)。
或者,您可以使用'&'
组合两个逻辑语句。如果两者都为TRUE,则'&'
采用两个元素并检查元素:
> 1:3 == 1 & 1:3 != 2
[1] TRUE FALSE FALSE
答案 5 :(得分:3)
my.df <- read.table(textConnection("
v1 v2 v3 v4
a v d c
a v d d
b n p g
b d d h
c k d c
c r p g
d v d x
d v d c
e v d b
e v d c"), header = TRUE)
my.df[which(my.df$v1 != "b" & my.df$v1 != "d" & my.df$v1 != "e" ), ]
v1 v2 v3 v4
1 a v d c
2 a v d d
5 c k d c
6 c r p g
答案 6 :(得分:1)
sub.data<-data[ data[,1] != "b" & data[,1] != "d" & data[,1] != "e" , ]
更大但更容易理解(我猜)并且可以与多列一起使用,即使使用!is.na( data[,1])
。
答案 7 :(得分:1)
还
library(dplyr)
data %>% filter(!v1 %in% c("b", "d", "e"))
或
data %>% filter(v1 != "b" & v1 != "d" & v1 != "e")
或
data %>% filter(v1 != "b", v1 != "d", v1 != "e")
由于逗号隐含&
运算符。