0

I got a funny task to do during coding my thesis. I have a 2D-matrix(or data.frame) like this:

     CACE        cheng     cheng2        ding    ding_ass        sun2
mean    0 -0.000467158 0.01219119 0.004284223 0.003803375 0.004204354
sd      0  0.131911914 0.14457078 0.074447198 0.055980336 0.072260046
            sun3
mean 0.004202419
sd   0.072266683

Above matrix is describing several models' performance(their mean and sd). I want to list them into my paper, so I need to reshape them like this:

    CACE_mean CACE_sd   cheng_mean  cheng_sd cheng2_mean cheng2_sd
[1,]         0       0 -0.000467158 0.1319119  0.01219119 0.1445708
       ding_mean   ding_sd ding_ass_mean ding_ass_sd   sun2_mean
[1,] 0.004284223 0.0744472   0.003803375  0.05598034 0.004204354
        sun2_sd   sun3_mean    sun3_sd
[1,] 0.07226005 0.004202419 0.07226668

It is like flatten a matrix or data.frame, but not a traditional long to wide reshaping task. I am wondering whether we can do it using high-level functions.

Data Original data(dput):

structure(c(0, 0, -0.000467157971792085, 0.131911914238178, 0.0121911908647192, 
0.144570781843054, 0.00428422254646622, 0.0744471979273107, 0.00380337457776962, 
0.0559803359990803, 0.00420435426517323, 0.0722600458117494, 
0.00420241918783969, 0.0722666828398023), .Dim = c(2L, 7L), .Dimnames = list(
    c("mean", "sd"), c("CACE", "cheng", "cheng2", "ding", "ding_ass", 
    "sun2", "sun3")))

My try

new_names = c(outer(row.names(a),colnames(a),function(x,y){paste(y,x,sep = '_')}))
new_data = t(data.frame(c(a),row.names = new_names))
rownames(new_data) <- NULL

It workes really well, but I wanna know some other ideas.

viky
  • 1
  • This is a similar question with a few alternate answers that really helped me recently: [Using R tidyr pivot_wide to get wide-form data from multiple column names and values (duplicate)](https://stackoverflow.com/questions/67561552/using-r-tidyr-pivot-wide-to-get-wide-form-data-from-multiple-column-names-and-va) – a11 May 28 '21 at 17:22

1 Answers1

1

How about a one line general solution? Assuming your data is in an object called d...

library(tidyverse)

as_tibble(d, rownames="Row") %>% pivot_wider(values_from=-Row, names_from=Row)

Giving

# A tibble: 1 x 14
  CACE_mean CACE_sd cheng_mean cheng_sd cheng2_mean cheng2_sd ding_mean ding_sd ding_ass_mean ding_ass_sd sun2_mean sun2_sd sun3_mean sun3_sd
      <dbl>   <dbl>      <dbl>    <dbl>       <dbl>     <dbl>     <dbl>   <dbl>         <dbl>       <dbl>     <dbl>   <dbl>     <dbl>   <dbl>
1         0       0  -0.000467    0.132      0.0122     0.145   0.00428  0.0744       0.00380      0.0560   0.00420  0.0723   0.00420  0.0723
Limey
  • 10,234
  • 2
  • 12
  • 32