Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unconventional data frame reshaping

Tags:

r

I'm trying to reshape table from

col1| col2|col3|id
v1  | v2  | v3 |1
v2  | v1  | v3 |2

to

col1|col2|id
v1  | v2 | 1
v2  | v3 | 1
v2  | v1 | 2
v1  | v3 | 2

Basically create pair of following columns for each id.

Sorry for not clear title, but not sure how to describe what I'm trying to do.

like image 980
AlienDeg Avatar asked Jan 03 '23 08:01

AlienDeg


2 Answers

for the case presented:

library(dplyr)
bind_rows(
    select(df, -col3),
    select(df,  col1=col2, col2=col3, id)
)

for more columns, assuming id is the last column:

library(dplyr)

NcolsToReduce <- ncol(df) - 2

lapply(1:NcolsToReduce, function(i){
  x <- select(df, i, i+1, id)
  names(x) <- c("col1", "col2", "id")
  x
  }) %>% bind_rows()

I think that'd work.

like image 119
Alex P Avatar answered Feb 27 '23 07:02

Alex P


The solution below should be working for an arbitrary number of columns and an id variable which can be any column (not just the last one).

It uses melt() to reshape from wide to long format and shift() to get the next row as second column of the column pair:

library(data.table)
melt(setDT(df), id.vars = "id")[
  , .(col1 = head(value, -1L), col2 = head(shift(value, 1L, type = "lead"), -1L)), by = id]
    id col1 col2
1:  1   v1   v2
2:  1   v2   v3
3:  2   v2   v1
4:  2   v1   v3

Data

library(data.table)
df <- fread(
  "col3| col2|col1|id
v1  | v2  | v3 |1
v2  | v1  | v3 |2",
  sep = "|")
like image 37
Uwe Avatar answered Feb 27 '23 07:02

Uwe