R - 使用匹配运算符时保留顺序 (%in%)
Posted
技术标签:
【中文标题】R - 使用匹配运算符时保留顺序 (%in%)【英文标题】:R - preserve order when using matching operators (%in%) 【发布时间】:2012-05-22 03:12:13 【问题描述】:我正在使用匹配运算符从单独的数据框中获取出现在矩阵中的值。但是,结果矩阵的值按照它们在数据框中出现的顺序排列,而不是在原始矩阵中。有没有办法使用匹配算子来保持原矩阵的顺序?
这是一个简单的例子:
vec=c("b","a","c"); vec
df=data.frame(row.names=letters[1:5],values=1:5); df
df[rownames(df) %in% vec,1]
这会产生> [1] 1 2 3
,这是"a" "b" "c"
出现在数据框中的顺序。但是,我想生成>[1] 2 1 3
,这是它们在原始向量中出现的顺序。
谢谢!
【问题讨论】:
【参考方案1】:由于行名索引也适用于向量,我们可以更进一步并定义:
'%ino%' <- function(x, table)
xSeq <- seq(along = x)
names(xSeq) <- x
Out <- xSeq[as.character(table)]
Out[!is.na(Out)]
我们现在得到了想要的结果:
df[rownames(df) %ino% vec, 1]
[1] 2 1 3
在函数内部,names() 会自动转换为字符,并使用 as.character() 更改表格,因此当 %ino% 的输入是数字时,这也可以正常工作:
LETTERS[1:26 %in% 4:1]
[1] "A" "B" "C" "D"
LETTERS[1:26 %ino% 4:1]
[1] "D" "C" "B" "A"
在 %in% 之后,删除缺失值:
LETTERS[1:26 %in% 3:-5]
[1] "A" "B" "C"
LETTERS[1:26 %ino% 3:-5]
[1] "C" "B" "A"
使用 %in% 时,逻辑序列沿被子集化对象的维度重复,而 %ino% 则不是这样:
data.frame(letters, LETTERS)[1:5 %in% 3:-5,]
letters LETTERS
1 a A
2 b B
3 c C
6 f F
7 g G
8 h H
11 k K
12 l L
13 m M
16 p P
17 q Q
18 r R
21 u U
22 v V
23 w W
26 z Z
data.frame(letters, LETTERS)[1:5 %ino% 3:-5,]
letters LETTERS
3 c C
2 b B
1 a A
【讨论】:
【参考方案2】:使用match
。
df[match(vec, rownames(df)), ]
# [1] 2 1 3
请注意,如果您在 vec
或 rownames(df)
中有重复值,match
可能不会按预期运行。
编辑: 我刚刚意识到行名索引会更简单、更优雅地解决您的问题:
df[vec, ]
# [1] 2 1 3
【讨论】:
使用行名索引的奖励积分,但两种解决方案都有效。谢谢!【参考方案3】:使用match(并为另一个向量中不匹配的元素去掉NA值):
Filter(function(x) !is.na(x), match(rownames(df), vec))
【讨论】:
实际上,如果您使用 nomatch=0 进行匹配,对于不匹配的项目,匹配将返回 0 而不是 NA。由于 [] 的行选择只是忽略了 0,因此您可以将匹配结果目录粘贴到 [] 中,无需调用过滤器以上是关于R - 使用匹配运算符时保留顺序 (%in%)的主要内容,如果未能解决你的问题,请参考以下文章
Dapper Extension LIKE 运算符在匹配字符串时以相反的顺序返回结果
在 R 中为 Google BigQuery 使用 IN 运算符