transpose tibble

Sometimes it's very useful to be able to swap rows and columns in a tibble. This can be done "manually," as shown in the very clever post by @dromano in this thread.

I've written a function (below) to do the transpose automagically. Any comments of suggestions would be much appreciated.

transpose_tibble <- function(input_tibble, name_of_first_column = NULL){
  # This function exchanges rows and columns of a tibble
  # AU: Dick Startz
  if (! ("tibble" %in% (.packages()))) stop("library tibble must be loaded")
  if (!is_tibble(input_tibble)) stop("Input to transpose_tibble must be a tibble")
  if ((!is.null(name_of_first_column)) & !is.character(name_of_first_column))
    stop("name_of_first_column in transpose_tibble must be character or omitted")
  
  output_tibble <- as_tibble(t(input_tibble), .name_repair = "universal")
  
  # take what were column names of input_tibble and make first column of
  # output_tibble
  output_tibble <- output_tibble |> add_column(colnames(input_tibble), .before = 1)
  
  # now take what was the first column of input_tibble and use for column names
  # substitute name_of_first_column if specified
  if (is.null(name_of_first_column))
    new_col_names <- output_tibble[1,]
  else
    new_col_names <- c(name_of_first_column, output_tibble[1, 2:ncol(output_tibble)])
  
  colnames(output_tibble) <- new_col_names
  
  # remove redundant 1st row now being used for column names
  output_tibble <- output_tibble |> slice(-1)
}
1 Like

The column_to_rownames() might already do some of what you're hoping to do, if I understand you correctly:

library(tidyverse)
starwars |> 
  select(1:4) |> 
  slice(1:4) -> input_tibble

input_tibble
#> # A tibble: 4 × 4
#>   name           height  mass hair_color
#>   <chr>           <int> <dbl> <chr>     
#> 1 Luke Skywalker    172    77 blond     
#> 2 C-3PO             167    75 <NA>      
#> 3 R2-D2              96    32 <NA>      
#> 4 Darth Vader       202   136 none

input_tibble |> 
  column_to_rownames("name") |> 
  t()
#>            Luke Skywalker C-3PO R2-D2 Darth Vader
#> height     "172"          "167" " 96" "202"      
#> mass       " 77"          " 75" " 32" "136"      
#> hair_color "blond"        NA    NA    "none"

Created on 2024-09-10 with reprex v2.0.2

However, it might also require converting to a data frame and then using the companion function rownames_to_column(), so in the end, it might not be any more compact.