6

我正在使用匹配运算符从单独的数据框中获取出现在矩阵中的值。但是,结果矩阵的值按照它们在数据框中出现的顺序排列,而不是在原始矩阵中。有没有办法使用匹配运算符保留原始矩阵的顺序?

这是一个简单的例子:

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它们在原始向量中出现的顺序。

谢谢!

4

3 回答 3

8

使用match.

df[match(vec, rownames(df)), ]
# [1] 2 1 3

请注意,如果您在vec或中有重复值rownames(df)match则可能不会按预期运行。

编辑: 我刚刚意识到行名索引将更简单优雅地解决您的问题:

df[vec, ]
# [1] 2 1 3
于 2012-05-14T16:01:21.943 回答
3

使用match(并为在另一个向量中不匹配的元素去掉 NA 值):

Filter(function(x) !is.na(x), match(rownames(df), vec))
于 2012-05-14T15:55:04.983 回答
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
于 2017-11-03T22:58:02.297 回答