我根据多个列的多个条件对数据帧进行子集化。我选择数据框中的行,这些行包含在三个不同列中的任何一列中的矢量“criteria”中定义的几个值中的任何一个。
我有一些有用的代码,但是想知道其他(更优雅?)的方法是做什么的。这就是我所做的:
criteria <-c(1:10)
subset1 <-subset(data, data[, "Col1"] %in% criteria | data[, "Col2"]
%in% criteria | data[, "Col3"] %in% criteria)
建议热烈欢迎。 (我是R初学者,所以对你所建议的非常简单的解释也受到热烈欢迎。)
答案 0 :(得分:13)
我不确定您是否需要两次apply
来电:
# Data
df=data.frame(x=1:4,Col1=c(11,12,3,13),Col2=c(9,12,10,13),Col3=c(9,13,42,23))
criteria=1:10
# Solution
df[apply(df [c('Col1','Col2','Col3')],1,function(x) any(x %in% criteria)),]
除非你想做很多专栏,否则说起来可能更具可读性:
subset(df, Col1 %in% criteria | Col2 %in% criteria | Col3 %in% criteria)
答案 1 :(得分:6)
我使用DF
而不是data
作为示例。
DF[apply(apply(as.matrix(DF[c("Col1","Col2","Col3")]),
c(1,2), `%in%`, criteria),
1, any),]
关于这是做什么的细分:
创建指定列的矩阵,并为该矩阵测试中的每个元素创建它是否包含其中一个条件。然后,对于该矩阵的每一行,查看是否有任何行元素是TRUE
。如果是这样,请保留原始数据集的相应行。
通过一个例子:
从虚拟数据开始:
DF <- data.frame(Col1=seq(1, by=2, length=10),
Col2=seq(3, by=3, length=10),
Col3=seq(7, by=1, length=10),
other=LETTERS[1:10])
看起来像
> DF
Col1 Col2 Col3 other
1 1 3 7 A
2 3 6 8 B
3 5 9 9 C
4 7 12 10 D
5 9 15 11 E
6 11 18 12 F
7 13 21 13 G
8 15 24 14 H
9 17 27 15 I
10 19 30 16 J
只拉出感兴趣的列。
> as.matrix(DF[c("Col1","Col2","Col3")])
Col1 Col2 Col3
[1,] 1 3 7
[2,] 3 6 8
[3,] 5 9 9
[4,] 7 12 10
[5,] 9 15 11
[6,] 11 18 12
[7,] 13 21 13
[8,] 15 24 14
[9,] 17 27 15
[10,] 19 30 16
检查每个条目与标准
> apply(as.matrix(DF[c("Col1","Col2","Col3")]), c(1,2), `%in%`, criteria)
Col1 Col2 Col3
[1,] TRUE TRUE TRUE
[2,] TRUE TRUE TRUE
[3,] TRUE TRUE TRUE
[4,] TRUE FALSE TRUE
[5,] TRUE FALSE FALSE
[6,] FALSE FALSE FALSE
[7,] FALSE FALSE FALSE
[8,] FALSE FALSE FALSE
[9,] FALSE FALSE FALSE
[10,] FALSE FALSE FALSE
测试一行中的任何值是否为TRUE
> apply(apply(as.matrix(DF[c("Col1","Col2","Col3")]), c(1,2), `%in%`, criteria), 1, any)
[1] TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
使用它来索引原始数据框。
> DF[apply(apply(as.matrix(DF[c("Col1","Col2","Col3")]), c(1,2), `%in%`, criteria), 1, any),]
Col1 Col2 Col3 other
1 1 3 7 A
2 3 6 8 B
3 5 9 9 C
4 7 12 10 D
5 9 15 11 E