将数据框中与匹配向量相符的行移动到末尾

9
我有一个包含超过300,000行的数据框。我希望选择匹配三个字符串的行,并将那些匹配的行移到数据框的末尾。我需要在最终的数据框中保留不匹配的行。最后,我的数据将被绘制并重新排序的数据框将被写入xls。
以下是一些示例数据:
mydata <- structure(list(id = structure(c(1L, 4L, 1L, 2L, 3L, 2L, 1L, 6L, 
5L, 2L, 1L, 3L, 4L), .Label = c("match1", "match2", "match3", 
"match4", "match8", "match9"), class = "factor"), A = structure(c(6L, 
5L, 7L, 4L, 10L, 7L, 8L, 8L, 9L, 4L, 3L, 2L, 1L), .Label = c("19", 
"2", "20", "3", "4", "6", "8", "H", "j", "T"), class = "factor"), 
    B = structure(c(2L, 2L, 2L, 3L, 4L, 2L, 4L, 5L, 2L, 3L, 5L, 
    3L, 1L), .Label = c("beside", "in", "out", "over", "under"
    ), class = "factor")), .Names = c("id", "A", "B"), row.names = c(NA, 
-13L), class = "data.frame")

它看起来像这样:

    id  A   B
match1  6   in
match4  4   in
match1  8   in
match2  3   out
match3  T   over
match2  8   in
match1  H   over
match9  H   under
match8  j   in
match2  3   out
match1  20  under
match3  2   out
match4  19  beside

我想使用这个字符串的向量将匹配的行移到数据框的末尾。

matchlist = c("match1", "match2", "match3")

生成的数据帧应该是这样的:
id  A   B
match4  4   in
match9  H   under
match8  j   in
match4  19  beside
match1  H   over
match1  6   in
match1  8   in
match1  20  under
match2  3   out
match2  8   in
match2  3   out
match3  T   over
match3  2   out

我需要保留不匹配的行。 我查看了这篇文章选择并按照向量排序数据帧的行但它会丢失不匹配的数据。


1
如果你指的是精确匹配,mydata[order(mydata$id %in% matchlist), ] - mt1022
4个回答

9

试试这个:

x <- as.character(df$id) %in% matchlist
rbind(df[!x,], df[x,])

       # id  A      B
# 2  match4  4     in
# 8  match9  H  under
# 9  match8  j     in
# 13 match4 19 beside
# 1  match1  6     in
# 3  match1  8     in
# 4  match2  3    out
# 5  match3  T   over
# 6  match2  8     in
# 7  match1  H   over
# 10 match2  3    out
# 11 match1 20  under
# 12 match3  2    out

2
我将这个标记为最佳答案,尽管 @Aleksandr Voitov 的回答也能运行。这个答案允许我在不创建太多 '|' 代码的情况下使用更多匹配字符串。 - aminards

5
考虑这个简短的 tidyverse 解决方案:
mydata %>%
  arrange(id %in% match_list)

3

以下是一种无需使用grep的解决方案:

matched <- mydata$id %in% matchlist
mydata2 <- rbind(mydata[!matched,], mydata[matched,])

当然,在rbind之前你可以对匹配的行进行排序,这样你就能得到和示例中完全相同的输出。


差不多同时发生的事情;-) 抱歉,我写回答时没有看到你的帖子。 - cno

1
top = mydata[-grep("match1|match2|match3", mydata$id),]
bottom = mydata[grep("match1|match2|match3", mydata$id),]
bottom = bottom[order(bottom$id),]
xls = rbind(top, bottom) 

这个答案和@989和cno发布的答案一样有效。谢谢。 - aminards

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接