0
votes

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()?

3

3 Answers

2
votes

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"))
1
votes

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")
0
votes

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)