有一个数据框:

tbl <- structure(list(t = c(1, 2, 3, 4, 5, 6), ak_b = c(909.021709977295, 
                                                 957.828244741177, 1037.13886373248, 1122.55029956928, 1275.07072070641, 
                                                 1415.38950815257), djk_b = c(2824.00501596013, 2975.62944634725, 
                                                                              3222.01914572632, 3487.36189890379, 3961.18824386354, 4397.10848122651
                                                 ), ak_a = c(909.021709977295, 957.828244741177, 1037.13886373248, 
                                                             1122.55029956928, 1275.07072070641, 1415.38950815257), djk_a = c(2824.00501596013, 
                                                                                                                              2975.62944634725, 3222.01914572632, 3487.36189890379, 3961.18824386354, 
                                                                                                                              4397.10848122651)), row.names = c(NA, -6L), class = "data.frame")

想把它变为如下形式:

t   value  class1 class2
1  909       ak        b
2  2824     djk       b
3  909        ak       a
...

即,将列名根据_拆分之后形成的字符作为class,并对应至相应的value上,请问大家有没有方便的解法呢?

    Hoas

    tbl <- structure(list(t = c(1, 2, 3, 4, 5, 6), ak_b = c(909.021709977295, 
                                                            957.828244741177, 1037.13886373248, 1122.55029956928, 1275.07072070641, 
                                                            1415.38950815257), djk_b = c(2824.00501596013, 2975.62944634725, 
                                                                                         3222.01914572632, 3487.36189890379, 3961.18824386354, 4397.10848122651
                                                            ), ak_a = c(909.021709977295, 957.828244741177, 1037.13886373248, 
                                                                        1122.55029956928, 1275.07072070641, 1415.38950815257), djk_a = c(2824.00501596013, 
                                                                                                                                         2975.62944634725, 3222.01914572632, 3487.36189890379, 3961.18824386354, 
                                                                                                                                         4397.10848122651)), row.names = c(NA, -6L), class = "data.frame")
    
    library(tidyr)
    tbl %>% pivot_longer(-1, names_to = "class") %>% separate(class, sep = "_", into = c("class1", "class2"))
    #> # A tibble: 24 x 4
    #>        t class1 class2 value
    #>    <dbl> <chr>  <chr>  <dbl>
    #>  1     1 ak     b       909.
    #>  2     1 djk    b      2824.
    #>  3     1 ak     a       909.
    #>  4     1 djk    a      2824.
    #>  5     2 ak     b       958.
    #>  6     2 djk    b      2976.
    #>  7     2 ak     a       958.
    #>  8     2 djk    a      2976.
    #>  9     3 ak     b      1037.
    #> 10     3 djk    b      3222.
    #> # … with 14 more rows

    这样?
    <sup>Created on 2021-05-31 by the reprex package (v2.0.0)</sup>

      Liechi 谢谢!正是如此!

      你的方式也是分步解决的思路,我之前尝试用 data.table 解决,只会拆开一列,而且新列的变量难以对应:

      library(data.table)
      melt(as.data.table(tbl), 1, measure = patterns('^ak_', '^djk_'))

        Hoas

        tbl <- structure(list(t = c(1, 2, 3, 4, 5, 6), ak_b = c(909.021709977295, 
                                                                957.828244741177, 1037.13886373248, 1122.55029956928, 1275.07072070641, 
                                                                1415.38950815257), djk_b = c(2824.00501596013, 2975.62944634725, 
                                                                                             3222.01914572632, 3487.36189890379, 3961.18824386354, 4397.10848122651
                                                                ), ak_a = c(909.021709977295, 957.828244741177, 1037.13886373248, 
                                                                            1122.55029956928, 1275.07072070641, 1415.38950815257), djk_a = c(2824.00501596013, 
                                                                                                                                             2975.62944634725, 3222.01914572632, 3487.36189890379, 3961.18824386354, 
                                                                                                                                             4397.10848122651)), row.names = c(NA, -6L), class = "data.frame")
        library(data.table)
        melt(as.data.table(tbl), 1)[, c("class1", "class2") := tstrsplit(variable, "_")][,variable:=NULL][]
        #>     t     value class1 class2
        #>  1: 1  909.0217     ak      b
        #>  2: 2  957.8282     ak      b
        #>  3: 3 1037.1389     ak      b
        #>  4: 4 1122.5503     ak      b
        #>  5: 5 1275.0707     ak      b
        #>  6: 6 1415.3895     ak      b
        #>  7: 1 2824.0050    djk      b
        #>  8: 2 2975.6294    djk      b
        #>  9: 3 3222.0191    djk      b
        #> 10: 4 3487.3619    djk      b
        #> 11: 5 3961.1882    djk      b
        #> 12: 6 4397.1085    djk      b
        #> 13: 1  909.0217     ak      a
        #> 14: 2  957.8282     ak      a
        #> 15: 3 1037.1389     ak      a
        #> 16: 4 1122.5503     ak      a
        #> 17: 5 1275.0707     ak      a
        #> 18: 6 1415.3895     ak      a
        #> 19: 1 2824.0050    djk      a
        #> 20: 2 2975.6294    djk      a
        #> 21: 3 3222.0191    djk      a
        #> 22: 4 3487.3619    djk      a
        #> 23: 5 3961.1882    djk      a
        #> 24: 6 4397.1085    djk      a
        #>     t     value class1 class2

        好久没有用 dt 了,这样可以,但觉得应该有更简单的办法。
        <sup>Created on 2021-05-31 by the reprex package (v2.0.0)</sup>

        base 版:

        tbl <- structure(list(t = c(1, 2, 3, 4, 5, 6), ak_b = c(909.021709977295, 
                                                         957.828244741177, 1037.13886373248, 1122.55029956928, 1275.07072070641, 
                                                         1415.38950815257), djk_b = c(2824.00501596013, 2975.62944634725, 
                                                                                      3222.01914572632, 3487.36189890379, 3961.18824386354, 4397.10848122651
                                                         ), ak_a = c(909.021709977295, 957.828244741177, 1037.13886373248, 
                                                                     1122.55029956928, 1275.07072070641, 1415.38950815257), djk_a = c(2824.00501596013, 
                                                                                                                                      2975.62944634725, 3222.01914572632, 3487.36189890379, 3961.18824386354, 
                                                                                                                                      4397.10848122651)), row.names = c(NA, -6L), class = "data.frame")
        
        
        . <- tbl
        . <- reshape(., direction = "long", idvar = 1, varying = list(2:5), v.names = "value", times = colnames(.)[-1])
        .[, c("class1", "class2")] <- read.table(text = .$time, sep = "_")
        within(., rm(time))
        #>         t     value class1 class2
        #> 1.ak_b  1  909.0217     ak      b
        #> 2.ak_b  2  957.8282     ak      b
        #> 3.ak_b  3 1037.1389     ak      b
        #> 4.ak_b  4 1122.5503     ak      b
        #> 5.ak_b  5 1275.0707     ak      b
        #> 6.ak_b  6 1415.3895     ak      b
        #> 1.djk_b 1 2824.0050    djk      b
        #> 2.djk_b 2 2975.6294    djk      b
        #> 3.djk_b 3 3222.0191    djk      b
        #> 4.djk_b 4 3487.3619    djk      b
        #> 5.djk_b 5 3961.1882    djk      b
        #> 6.djk_b 6 4397.1085    djk      b
        #> 1.ak_a  1  909.0217     ak      a
        #> 2.ak_a  2  957.8282     ak      a
        #> 3.ak_a  3 1037.1389     ak      a
        #> 4.ak_a  4 1122.5503     ak      a
        #> 5.ak_a  5 1275.0707     ak      a
        #> 6.ak_a  6 1415.3895     ak      a
        #> 1.djk_a 1 2824.0050    djk      a
        #> 2.djk_a 2 2975.6294    djk      a
        #> 3.djk_a 3 3222.0191    djk      a
        #> 4.djk_a 4 3487.3619    djk      a
        #> 5.djk_a 5 3961.1882    djk      a
        #> 6.djk_a 6 4397.1085    djk      a

        <sup>Created on 2021-06-01 by the reprex package (v2.0.0)</sup>