What is the best way to transpose a data.frame in R and to set one of the columns to be the header for the new transposed table?

Viewed 63477

What is the best way to transpose a data.frame in R and to set one of the columns to be the header for the new transposed table? I have coded up a way to do this below. As I am still new to R. I would like suggestions to improve my code as well as alternatives that would be more R-like. My solution is also unfortunately a bit hard coded (i.e. the new column headings are in a certain location).

# Assume a data.frame called fooData
# Assume the column is the first column before transposing

# Transpose table
fooData.T <- t(fooData)

# Set the column headings
colnames(fooData.T) <- test[1,]

# Get rid of the column heading row
fooData.T <- fooData.T[2:nrow(fooData.T), ]

#fooData.T now contains a transposed table with the first column as headings
7 Answers

You can do it even in one line:

fooData.T <- setNames(data.frame(t(fooData[,-1])), fooData[,1])

There are already great answers. However, this answer might be useful for those who prefer brevity in code.

Here are my two cents using dplyr for a data.frame that has grouping columns and an id column.

id_transpose <- function(df, id){
  df %>% 
    ungroup() %>% 
    select(where(is.numeric)) %>% 
    t() %>% 
    as_tibble() %>% 
    setNames(., df %>% pull({{id}}))
}

Here is another tiyderse/dplyr approach taken from here.

mtcars %>%
  tibble::rownames_to_column() %>%  
  tidyr::pivot_longer(-rowname) %>% 
  tidyr::pivot_wider(names_from=rowname, values_from=value)

Use transpose from data.table, suppose the column you want to use as header after transpose is the variable group.

fooData.transpose = fooData %>% transpose (make.name = "group")

In addition, if you want to assign a name for the transposed column name, use argument keep.names.

fooData.transpose = fooData %>% transpose (make.name = "group", keep.names = "column_name")

There's now a dedicated function to transpose data frames, rotate_df from the sjmisc package. If the desired names are in the first column of the original df, you can achieve this in one line thanks to the cn argument.

Here's an example data frame:

df <- data.frame(name = c("Mary", "John", "Louise"), class = c("A", "A", "B"), score = c(40, 75, 80))

df
#    name class score
#1   Mary     A    40
#2   John     A    75
#3 Louise     B    80

Executing the function with cn = T:

rotate_df(df, cn = T)

#      Mary John Louise
#class    A    A      B
#score   40   75     80
Related