Search code examples
rsortingtimetime-seriestimestamp

Sort the column (by time) from smallest to the largest


I have this dataframe (in 1-min frequency) where the columns represent the timestamps. I want to sort these columns from early time to later time (e.g., from 00:00 to 23:59). Now it starts with 06:43 till 06:42.

    > head(data3)
# A tibble: 6 × 1,440
  `06:43` `06:44` `06:45` `06:46` `06:47` `06:48` `06:49` `06:50` `06:51` `06:52`
  <chr>   <chr>   <chr>   <chr>   <chr>   <chr>   <chr>   <chr>   <chr>   <chr>  
1 3       2       2       3       3       2       1       0       1       1      
2 7       6       6       6       6       6       6       5       5       6      
3 10      9       9       7       5       3       M       M       M       M      
4 M       M       M       M       M       M       M       M       M       M      

At first, for the list of small columns names, I think of this usual way

col_order <- c("00:00", "00:01", ..., "23:59") # write down all columns
data3 <- data3[, col_order]
data3

But obviously, it is too much to write down all the col names there (1440 columns) and it seems 'silly'.

Is there anyway to do it in R? Kindly advise. Thank you.


Solution

  • Here is reproducible data:

    df <- structure(list("06:43" = c("3", "7", "10", "M"), "06:44" = c("2", "6", "9", "M"), "12:45" = c("2", "6", "9", "M"), "06:46" = c("3", "6", "7", "M"), "06:47" = c("3", "6", "5", "M"), "06:48" = c("2", "6", "3", "M"), "06:49" = c("1", "6", "M", "M"), "06:50" = c("0", "5", "M", "M"), "06:51" = c("1", "5", "M", "M"), "06:42" = c("1", "6", "M", "M")), class = "data.frame", row.names = c("1", "2", "3", "4"))
    df
    #   06:43 06:44 12:45 06:46 06:47 06:48 06:49 06:50 06:51 06:42
    # 1     3     2     2     3     3     2     1     0     1     1
    # 2     7     6     6     6     6     6     6     5     5     6
    # 3    10     9     9     7     5     3     M     M     M     M
    # 4     M     M     M     M     M     M     M     M     M     M
    

    From here, sorting the column names is direct:

    df[,sort(names(df))]
    #   06:42 06:43 06:44 06:46 06:47 06:48 06:49 06:50 06:51 12:45
    # 1     1     3     2     3     3     2     1     0     1     2
    # 2     6     7     6     6     6     6     6     5     5     6
    # 3     M    10     9     7     5     3     M     M     M     9
    # 4     M     M     M     M     M     M     M     M     M     M
    

    Note that if, per your comments, you have a column named "6:42" with no leading zero, then this will break alphabetic sorting. In that case, then perhaps:

    names(df)[10] <- "6:42" # just to show it, don't do this
    df[,order(as.numeric(sub(":", ".", names(df))))]
    #   6:42 06:43 06:44 06:46 06:47 06:48 06:49 06:50 06:51 12:45
    # 1    1     3     2     3     3     2     1     0     1     2
    # 2    6     7     6     6     6     6     6     5     5     6
    # 3    M    10     9     7     5     3     M     M     M     9
    # 4    M     M     M     M     M     M     M     M     M     M