Debora Casagrande
Debora Casagrande

Reputation: 1

Is there a fast way to append all columns of a data frame into a single column?

I can't find a fast way to convert my data frame into a vector composed of the df columns. I have a df made of x rows per y columns and I'd like to have a vector or a list or a df (the class doesn't really matter) that is x per y rows and only 3columns of which one is that of the rownames (repeated for every column), the second is that of the listed values(data) and the third is that of the repeated col names. To better explain, I want to go from this

c1 c2 c3
n1 0.1 0.2 0.3
n2 0.4 0.5 0.6
n3 0.7 0.8 0.9

to this

values colname
n1 0.1 c1
n2 0.4 c1
n3 0.7 c1
n1 0.2 c2
n2 0.5 c2
n3 0.8 c2

Is there a fast way to manipulate this dataframe or the only way is to grab column by column and rbind()?

Upvotes: 0

Views: 1775

Answers (3)

barboulotte
barboulotte

Reputation: 405

A proposition using the melt() function of the reshape2 package :

df <- read.table(header = TRUE, text = "
n  c1  c2  c3
n1 0.1 0.2 0.3
n2 0.4 0.5 0.6
n3 0.7 0.8 0.9
")

reshape2::melt(df,
               id.vars = "n",
               mesure.vars = c("c1":"c3"),
               variable.name = "var",
               value.name = "val")
#>    n var val
#> 1 n1  c1 0.1
#> 2 n2  c1 0.4
#> 3 n3  c1 0.7
#> 4 n1  c2 0.2
#> 5 n2  c2 0.5
#> 6 n3  c2 0.8
#> 7 n1  c3 0.3
#> 8 n2  c3 0.6
#> 9 n3  c3 0.9

# Created on 2021-02-02 by the reprex package (v0.3.0.9001)

Upvotes: 0

GKi
GKi

Reputation: 39657

You can use stack:

cbind(row = rownames(x), stack(x))
#  row values ind
#1  n1    0.1  c1
#2  n2    0.4  c1
#3  n3    0.7  c1
#4  n1    0.2  c2
#5  n2    0.5  c2
#6  n3    0.8  c2
#7  n1    0.3  c3
#8  n2    0.6  c3
#9  n3    0.9  c3

Data

x <- read.table(header=TRUE, text="c1   c2  c3
n1  0.1     0.2     0.3
n2  0.4     0.5     0.6
n3  0.7     0.8     0.9")

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 388982

In base R :

result <- data.frame(row = rownames(df1), 
                     name = rep(names(df1), each = ncol(df1)), 
                     value = unlist(df1), row.names = NULL)

result
#  row name value
#1  n1   c1   0.1
#2  n2   c1   0.4
#3  n3   c1   0.7
#4  n1   c2   0.2
#5  n2   c2   0.5
#6  n3   c2   0.8
#7  n1   c3   0.3
#8  n2   c3   0.6
#9  n3   c3   0.9

Or using tidyrs pivot_longer :

library(dplyr)
library(tidyr)

df1 %>% rownames_to_column('row') %>% pivot_longer(cols = -row)

data

df1 <- structure(list(c1 = c(0.1, 0.4, 0.7), c2 = c(0.2, 0.5, 0.8), 
    c3 = c(0.3, 0.6, 0.9)), class = "data.frame", 
    row.names = c("n1", "n2", "n3"))

Upvotes: 2

Related Questions