简体   繁体   中英

Reorder data.frame and rewrite rownames?

I have a data.frame like this:

id<-c("001-020", "001-010", "001-051")
name<-c("Fred", "Sue", "Liam")
df<-data.frame(id, name)

I tried:

df[with(df, order(id)), ]
#        id name
# 2 001-010  Sue
# 1 001-020 Fred
# 3 001-051 Liam

which orders the data.frame correctly, but doesn't touch the rownames.

How may I reorder the data.frame using the ascending order of the id field and rewrite the rownames in one go ?

You could try

 newdf <- df[with(df, order(id)), ]
 row.names(newdf) <- NULL

Or it can be done in a single step

 newdf <- `row.names<-`(df[with(df,order(id)),], NULL)

Setting row.names to NULL will also work when you have an empty data.frame.

  d1 <- data.frame()
  row.names(d1) <- NULL
  d1
  #data frame with 0 columns and 0 rows

If we do the same with 1:nrow

 row.names(d1) <-1:nrow(d1)
 #Error in `row.names<-.data.frame`(`*tmp*`, value = c(1L, 0L)) : 
 #invalid 'row.names' length

Or another option is data.table

 library(data.table)#v1.9.4+
 setorder(setDT(df), id)[]

Or

 setDT(df)[order(id)]

Or using sqldf

 library(sqldf)
 sqldf('select * from df
        order by id')

You can simply assign new rownames :

df2 <- df[with(df, order(id)), ]
rownames(df2) <- 1:nrow(df2)

And a cleaner solution with magrittr :

library(magrittr)
df %>% extract(order(df$id), ) %>% set_rownames(1:nrow(df))

I am surprised it's not in the previous answers. What you are looking for is arrange from plyr :

library(plyr)

arrange(df, id)
#       id name
#1 001-010  Sue
#2 001-020 Fred
#3 001-051 Liam

Since row names are stored as an attribute on the object, perhaps structure() would be appropriate here:

structure(df[order(df$id),],row.names=rownames(df));
##        id name
## 1 001-010  Sue
## 2 001-020 Fred
## 3 001-051 Liam

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM