简体   繁体   中英

How to split data.frame to equal columns

Here is sample data:

df <- data.frame(t(data.frame(seq(1,10,1)))); rownames(df) <- NULL; 
colnames(df) <- letters[1:ncol(df)]
df

I would like to arrange the new data.frame so that it always has 6 columns, the next row (after splinting since ncol>6) would contain the next 6 column names and next row their values. The last row if ncol<6 the values are filled with empty string including the column names.

Here is desired output:

  a b c d e f 
1 1 2 3 4 5 6  
2 g h i j 
3 7 8 9 10 

Another example:

df <- data.frame(t(data.frame(seq(1,15,1)))); rownames(df) <- NULL; 
colnames(df) <- letters[1:ncol(df)]
df

  a b c d e f
1 1 2 3 4 5 6
2 g h i j k l
3 7 8 9 10 11 12
4 m n o
5 13 14 15

EDIT:

The way to approach it possibly is to:

n <- 6
ncl <- nrow(df)

s <- split(df, rep(1:ceiling(ncl/n), each=n, length.out=ncl))
s

s1 <- split(rownames(df), rep(1:ceiling(ncl/n), each=n, length.out=ncl))
s1

combine every second split of s and s1

s1[c(TRUE,FALSE)]

For the life of me I can't figure out a use-case for this... but for sake of the provided examples...

seq(1, ncol(df), by = 6) %>% {
    starts <- .
    ends <- c(lead(.,1,NULL)-1, ncol(df))
    base_df <- df[,starts[[1]]:ends[[1]]]
    rbind(base_df, rbind.pages(Map(function(s, e){
       d <- df[,seq(s, e)]
       data.frame(rbind(colnames(d), d)) %>% setNames(colnames(base_df)[1:length(.)])
    }, s = starts[-1], e = ends[-1]))
        )  %>% 
        mutate_all(function(x){
            ifelse(!is.na(x), x, "")
        })
}

   a  b  c  d  e  f
1  1  2  3  4  5  6
2  g  h  i  j  k  l
3  7  8  9 10 11 12
4  m  n  o         
5 13 14 15   

EDIT to coerce NA to 'empty string'

Here's a way, not so pretty, but this is an ugly question :D

library(tibble)
library(dplyr)
df1 <- matrix(c(names(df),rep('',6 - ncol(df)%%6)) %>% unlist, ncol=6,byrow=T) %>% as_tibble %>% rowid_to_column()
df2 <- matrix(c(df       ,rep('',6 - ncol(df)%%6)) %>% unlist, ncol=6,byrow=T) %>% as_tibble %>% rowid_to_column()
bind_rows(df1,df2) %>% arrange(rowid) %>% select(-1) %>% setNames(.[1,]) %>% slice(-1)

# # A tibble: 3 x 6
#       a     b     c     d     e     f
#   <chr> <chr> <chr> <chr> <chr> <chr>
# 1     1     2     3     4     5     6
# 2     g     h     i     j            
# 3     7     8     9    10

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM