132

I need to transpose a large data frame and so I used:

df.aree <- t(df.aree)
df.aree <- as.data.frame(df.aree)

This is what I obtain:

df.aree[c(1:5),c(1:5)]
                         10428        10760        12148        11865
    name                M231T3       M961T5       M960T6      M231T19
    GS04.A        5.847557e+03 0.000000e+00 3.165891e+04 2.119232e+04
    GS16.A        5.248690e+04 4.047780e+03 3.763850e+04 1.187454e+04
    GS20.A        5.370910e+03 9.518396e+03 3.552036e+04 1.497956e+04
    GS40.A        3.640794e+03 1.084391e+04 4.651735e+04 4.120606e+04    

My problem is the new column names(10428, 10760, 12148, 11865) that I need to eliminate because I need to use the first row as column names.

I tried with col.names() function but I haven't obtain what I need.

Do you have any suggestion?

EDIT

Thanks for your suggestion!!! Using it I obtain:

df.aree[c(1:5),c(1:5)]
                        M231T3       M961T5       M960T6      M231T19
    GS04.A        5.847557e+03 0.000000e+00 3.165891e+04 2.119232e+04
    GS16.A        5.248690e+04 4.047780e+03 3.763850e+04 1.187454e+04
    GS20.A        5.370910e+03 9.518396e+03 3.552036e+04 1.497956e+04
    GS40.A        3.640794e+03 1.084391e+04 4.651735e+04 4.120606e+04
    GS44.A        1.225938e+04 2.681887e+03 1.154924e+04 4.202394e+04

Now I need to transform the row names(GS..) in a factor column....

Jaap
  • 81,064
  • 34
  • 182
  • 193
Riccardo
  • 1,885
  • 3
  • 15
  • 22
  • 1
    Have you tried `colnames(df.aree)<-df.aree[1,];df.aree<-df.aree[2:nrow(df.aree),]`? –  Jul 21 '11 at 15:54
  • 5
    Data frames aren't naturally meant to be transposable. If yours is, then perhaps it should be in matrix form instead. – Richie Cotton Jul 21 '11 at 16:01
  • Agree; `t`ing data frame is also quite inefficient. If you can, use matrix. – mbq Jul 21 '11 at 16:31
  • 5
    Transposing a data.frame that contains a string column in it turns ALL values into strings! NOT good. See my answer below for a work-around. – Tommy Jul 21 '11 at 16:50

6 Answers6

133

You'd better not transpose the data.frame while the name column is in it - all numeric values will then be turned into strings!

Here's a solution that keeps numbers as numbers:

# first remember the names
n <- df.aree$name

# transpose all but the first column (name)
df.aree <- as.data.frame(t(df.aree[,-1]))
colnames(df.aree) <- n
df.aree$myfactor <- factor(row.names(df.aree))

str(df.aree) # Check the column types
Tommy
  • 39,997
  • 12
  • 90
  • 85
  • If you want to use transpose with data.frame, df <- df %>% mutate_if(is.character,as.numeric) can be used to change characters back to numeric. – Dan Tarr Oct 06 '22 at 01:10
84

You can use the transpose function from the data.table library. Simple and fast solution that keeps numeric values as numeric.

library(data.table)

# get data
data("mtcars")

# transpose
t_mtcars <- transpose(mtcars)

# get row and colnames in order
colnames(t_mtcars) <- rownames(mtcars)
rownames(t_mtcars) <- colnames(mtcars)
ah bon
  • 9,293
  • 12
  • 65
  • 148
rafa.pereira
  • 13,251
  • 6
  • 71
  • 109
  • 6
    also, `setnames(t_mtcars, rownames(mtcars))` would be the `data.table`-way of setting names on a data.table (and if using a `data.table` object you wouldn't set the `rownames`) – SymbolixAU Oct 05 '17 at 22:30
  • 2
    Also, within `data.table::transpose` you can use the arguments `make.names` to select the column (usually a character vector) whose names will become the column names for the transposed data.frame. You can also use the argument `keep.names` to choose a column name for the new column (a character vector) which will store the previous column names from the pre-transposed data.frame). – Brandon Nov 06 '22 at 07:21
50
df.aree <- as.data.frame(t(df.aree))
colnames(df.aree) <- df.aree[1, ]
df.aree <- df.aree[-1, ]
df.aree$myfactor <- factor(row.names(df.aree))
Frank
  • 2,738
  • 19
  • 30
5

With tidyr, one can transpose a dataframe with "pivot_longer" and then "pivot_wider".

To transpose the widely used mtcars dataset, you should first transform rownames to a column (the function rownames_to_column creates a new column, named "rowname").

library(tidyverse)

mtcars %>% 
rownames_to_column() %>% 
pivot_longer(!rowname, names_to = "col1", values_to = "col2") %>% 
pivot_wider(names_from = "rowname", values_from = "col2")
BMLopes
  • 546
  • 6
  • 10
4

Take advantage of as.matrix:

# keep the first column 
names <-  df.aree[,1]

# Transpose everything other than the first column
df.aree.T <- as.data.frame(as.matrix(t(df.aree[,-1])))

# Assign first column as the column names of the transposed dataframe
colnames(df.aree.T) <- names
Gigi
  • 587
  • 5
  • 12
0

You can give another name for transpose matrix

df.aree1 <- t(df.aree)
df.aree1 <- as.data.frame(df.aree1)
user438383
  • 5,716
  • 8
  • 28
  • 43
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 05 '22 at 06:54