Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving some rows of a data frame to the end based on a match vector

Tags:

dataframe

r

match

I have a data frame with >300000 rows. I want to select matches to three strings and move those rows that match to the end of the data frame. I need to keep the rows that don't match in the final data frame. In the end, my data will be plotted and the reordered data frame will be written to xls.

Here is some example data:

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")

Which looks like this:

    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

I want to use this vector of strings to move rows that match to the end of the data frame.

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

The resulting data frame would look like this:

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

I need to retain the non-matching rows. I looked at this post Select and sort rows of a data frame based on a vector but it loses the non-matching data.

like image 352
aminards Avatar asked Mar 28 '17 15:03

aminards


1 Answers

Try this:

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
like image 113
989 Avatar answered Sep 18 '22 22:09

989