Mette
Mette

Reputation: 325

How to transform a dataframe so values move one row down per column in R?

I have a dataframe where data are sorted like that:


df <- data.frame('a'= c('b'), 'c'=c('d'), 'e'= c('f'), 'g'= c('h'), 'i'=c('j'))

df
#   a c e g i
# 1 b d f h j

Is there a way that I can transform the dataframe, so data move one row down (lineary) for each column? Except from the first row where the value stays where it is:

df_expected <- data.frame('a'= c('b', '','','',''), 'c'=c('','d','','',''), 'e'= c('', '', 'f', '',''), 'g'= c('','','','h',''), 'i'=c('','','','','j'))

df_expected

#   a c e g i
# 1 b        
# 2   d      
# 3     f    
# 4       h  
# 5         j

Upvotes: 2

Views: 119

Answers (3)

ThomasIsCoding
ThomasIsCoding

Reputation: 101257

You can try

`diag<-`(matrix("", length(df), length(df)), unlist(df))

or

replace(u <- `diag<-`(diag(length(df)), unlist(df)), u == "0", "")

which gives

     [,1] [,2] [,3] [,4] [,5]
[1,] "b"  ""   ""   ""   ""
[2,] ""   "d"  ""   ""   ""
[3,] ""   ""   "f"  ""   ""
[4,] ""   ""   ""   "h"  ""
[5,] ""   ""   ""   ""   "j"

Upvotes: 1

yinchi
yinchi

Reputation: 36

For your specific data frame, using diag() is much easier. The following code should work in general cases.

df_expected <- matrix(0, ncol = ncol(df), nrow = nrow(df) + ncol(df) - 1)
df_expected[1:length(df[,1]),1] <- df[,1]
for(i in 2:ncol(df)){
  tmp <- c(rep(0, i-1), df[, i])
  df_expected[1:i,i] <- tmp
}
df_expected <- as.data.frame(df_expected)
names(df_expected) <- names(df)

Upvotes: 1

akrun
akrun

Reputation: 887078

We can use diag

m1 <- diag(ncol(df))
m1[m1 == 1] <- unlist(df)
as.data.frame(m1)

Or create a matrix

m2 <- matrix('', ncol = ncol(df), nrow = ncol(df),
     dimnames = list(NULL, names(df)))
m2[upper.tri(m2) == lower.tri(m2)] <- unlist(df)

Upvotes: 3

Related Questions