admin管理员组

文章数量:1302266

I have a dataframe that I have successfully transposed using the t function present in base R. However I'd like to change the column names and row names to be part of the dataframe. I'll use the iris data as an example.

# Transpose iris data
iris.transposed <- t(iris)

# View the transposed DF
View(iris.transposed)

In the screenshot attached, the column header in the transposed DF contains columns V1, V2, V2, V4, e.t.c. However, I'd like the row species to the the column header.

The same goes for the rows. Sepal.length, sepal.width, petal.length.. e.t.c are rownames. However, I'd like them to be part of the dataframe as observations.

How do I finalise this?

I have a dataframe that I have successfully transposed using the t function present in base R. However I'd like to change the column names and row names to be part of the dataframe. I'll use the iris data as an example.

# Transpose iris data
iris.transposed <- t(iris)

# View the transposed DF
View(iris.transposed)

In the screenshot attached, the column header in the transposed DF contains columns V1, V2, V2, V4, e.t.c. However, I'd like the row species to the the column header.

The same goes for the rows. Sepal.length, sepal.width, petal.length.. e.t.c are rownames. However, I'd like them to be part of the dataframe as observations.

How do I finalise this?

Share asked Feb 11 at 8:09 andrewandrew 2,0776 gold badges29 silver badges46 bronze badges 3
  • 4 It is not really advised to have column with the same names. What do you expect iris.transposed$setosa to return? Note also that using t converts your data.frame to a matrix. – Maël Commented Feb 11 at 8:14
  • 5 There's very rarely a good reason to have duplicated column names which is why most data frame creation functions invoke make.unique() on the names by default. Why do you want this? – Iroha Commented Feb 11 at 8:15
  • That said, you can use colnames(iris.transposed) <- iris.transposed["Species", ] and iris.transposed$col <- rownames(iris.transposed) – Maël Commented Feb 11 at 8:16
Add a comment  | 

2 Answers 2

Reset to default 1

Something like this?
Note that the first argument of ave tells its return value class. The new values are not factor levels (Species only has 3 levels) and when the serial numbers are pasted NA's are generated. That's why the first iris[[5]] must be coerced to character.
The result is a "matrix", not a data.frame.

# remove the last column, it's not a numeric column, it's a factor
iris.transposed <- t(iris[-5])
# the first argument of ave() tells the return value class
new_names <- ave(as.character(iris[[5]]), iris[[5]], FUN = \(x) paste0(x, seq_along(x)))
colnames(iris.transposed) <- new_names
# see the matrix structure
str(iris.transposed)
#>  num [1:4, 1:150] 5.1 3.5 1.4 0.2 4.9 3 1.4 0.2 4.7 3.2 ...
#>  - attr(*, "dimnames")=List of 2
#>   ..$ : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
#>   ..$ : chr [1:150] "setosa1" "setosa2" "setosa3" "setosa4" ...

Created on 2025-02-11 with reprex v2.1.1


tidyverse solution

A tidyverse solution is probably better, the output automatically includes the column names of length and width.

library(tidyverse)

iris %>% 
  mutate(Species = paste(Species, row_number(), sep = "_"), .by = Species) %>%
  pivot_longer(-Species, names_to = "Measure") %>%
  pivot_wider(
    id_cols = Measure,
    names_from = Species,
    values_from = value
  )

Here's a general function to do what you want:

t2 <- function(data, col) {
  t.data <- data.frame(names(data[-col]), t(data[-col]))
  colnames(t.data) <- c(names(data[col]), as.character(data[,col]))
  rownames(t.data) <- NULL
  t.data
}

Call it on the iris dataset:

    t2(iris, col=5)
       Species setosa setosa setosa setosa setosa setosa setosa
1 Sepal.Length    5.1    4.9    4.7    4.6    5.0    5.4    4.6
2  Sepal.Width    3.5    3.0    3.2    3.1    3.6    3.9    3.4
3 Petal.Length    1.4    1.4    1.3    1.5    1.4    1.7    1.4
4  Petal.Width    0.2    0.2    0.2    0.2    0.2    0.4    0.3

本文标签: rEdit row and column names in a transposed data frameStack Overflow