在多个条件下对R中的数据框进行子集化
我想通过告诉R什么不保留在新的数据框中来对数据框进行分类。 这是一个简单的示例数据框:
data v1 v2 v3 v4 avdc avdd bnpg bddhckdccrpg dvdx dvdc evdb evdc
如果列v1有一个“b”,“d”或“e”,我想摆脱那行观察,产生下面的dataframe:
v1 v2 v3 v4 avdc avdd ckdccrpg
我已经成功地一次性用掉了一个
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%
,但似乎并不存在。 有任何想法吗?
那!
应该是在声明的外面:
data[!(data$v1 %in% c("b", "d", "e")), ] v1 v2 v3 v4 1 avdc 2 avdd 5 ckdc 6 crpg
尝试这个
subset(data, !(v1 %in% c("b","d","e")))
您也可以通过将事件分解为单独的逻辑语句来实现这一点。
subset(my.df, my.df$v1 != "b" & my.df$v1 != "d" & my.df$v1 != "e")
这不是优雅的,需要更多的代码,但可能更新的R用户可读性。 正如在上面的评论中指出的, subset
是一个“便利”function,交互式工作时最好使用。
data <- data[-which(data[,1] %in% c("b","d","e")),]
这个答案更多的是为了解释为什么,而不是如何。 R中的'=='
运算符与'+'
运算符相同。 它将左侧的元素与右侧的元素(每个元素)进行匹配。 例如:
> 1:3 == 1:3 [1] TRUE TRUE TRUE
这里第一个testing是1==1
这是真,第二个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
testing一个元素是否在向量中的正确运算符实际上是'%in%'
,它只向左元素进行向量化(对于左向量中的每个元素,testing它是否是右元素中的任何对象的一部分) 。
或者,您可以使用'&'
来组合两个逻辑语句。 如果两个元素都为真,则'&'
接受两个元素并检查元素:
> 1:3 == 1 & 1:3 != 2 [1] TRUE FALSE FALSE
my.df <- read.table(textConnection(" v1 v2 v3 v4 avdc avdd bnpg bddhckdccrpg dvdx dvdc evdb evdc"), header = TRUE) my.df[which(my.df$v1 != "b" & my.df$v1 != "d" & my.df$v1 != "e" ), ] v1 v2 v3 v4 1 avdc 2 avdd 5 ckdc 6 crpg
sub.data<-data[ data[,1] != "b" & data[,1] != "d" & data[,1] != "e" , ]
较大,但很容易理解(我猜),可以使用多列,即使!is.na( data[,1])
。