Конкатенация файлов .xlsx с последовательными именами столбцов в R - PullRequest
0 голосов
/ 22 марта 2020

Допустим, у меня есть такие фреймы данных:

df1 <- as.data.frame(rbind(c(182, 142, 120), c(640, 381, 192)))
colnames(df1) <- c("Q1", "Q2", "Q3")

df2 <- as.data.frame(rbind(c(73, 51, 67, 38), c(62, 42, 33, 46), c(84, 91, 77, 56)))
colnames(df2) <- c("Q4", "Q5", "Q6", "Q7")

df3 <- as.data.frame(t(c(1820, 2114)))
colnames(df3) <- c("Q8", "Q9")

df1
  Q1  Q2  Q3
1 182 142 120
2 640 381 192

df2
  Q4 Q5 Q6 Q7
1 73 51 67 38
2 62 42 33 46
3 84 91 77 56

df3
  Q8   Q9
1 1820 2114

Обратите внимание, что у меня есть 3 фрейма данных различной длины. Чего я хотел бы добиться, так это объединить один над другим, указав при этом соответствующие имена столбцов.

Желаемый результат:

  1 Q1   Q2   Q3
  2 182  142  120
  3 640  381  192
  4 Q4   Q5   Q6   Q7
  5 73   51   67   38
  6 62   42   33   46
  7 84   91   77   56
  8 Q8   Q9
  9 1820 2114

Я пытался сначала сделайте это, экспортировав файлы в .xlsx, а затем конкатенируя их, но мне удалось только отсортировать их cbind

Заранее спасибо

Ответы [ 2 ]

3 голосов
/ 22 марта 2020

Не уверен, имеет ли ваш запрошенный формат много смысла в R, так как

  1. все элементы столбца data.frame должны принадлежать к одному классу, поэтому будут принудительно приведены к символу, как только вы добавляете строки заголовка в виде строк

  2. все строки data.frame должны быть одинаковой длины, следовательно, вам нужно будет пропатчить data.frames с меньшим количеством столбцов со столбцами NA

Но ниже будет одно решение, которое даст вам data.frame, содержащий данные так, как вы показали в желаемом выводе:

df1 <- as.data.frame(rbind(c(182, 142, 120), c(640, 381, 192)))
colnames(df1) <- c("Q1", "Q2", "Q3")

df2 <- as.data.frame(rbind(c(73, 51, 67, 38), c(62, 42, 33, 46), c(84, 91, 77, 56)))
colnames(df2) <- c("Q4", "Q5", "Q6", "Q7")

df3 <- as.data.frame(t(c(1820, 2114)))
colnames(df3) <- c("Q8", "Q9")

maxCol <- max(ncol(df1), ncol(df2), ncol(df3))

match_df <- function(x, ncol){
    delta <- ncol - dim(x)[2]
    out <- {
        if(delta > 0) unname(data.frame(append((rbind(colnames(x), unname(x))), 
            c(rep(NA, delta))))) else 
        unname(data.frame((rbind(colnames(x), unname(x)))))[, seq_len(ncol)]}
    colnames(out) <- paste0("V", seq_len(ncol))
    out
}
out <- unname(do.call(rbind, lapply(list(df1, df2, df3), match_df, ncol=maxCol)))
print(out, na.print = "")
#>                   
#> 1   Q1   Q2  Q3   
#> 2  182  142 120   
#> 3  640  381 192   
#> 4   Q4   Q5  Q6 Q7
#> 5   73   51  67 38
#> 6   62   42  33 46
#> 7   84   91  77 56
#> 8   Q8   Q9       
#> 9 1820 2114

Более естественный способ в R, который поддерживает данные о цифрах c в виде чисел c, состоит в том, чтобы «сортировать их», как вы выразились, и, если вы будете sh, плавить и фильтровать их, чтобы удалить Значения NA:

library(data.table)
melt(rbindlist(list(df1, df2, df3), fill=TRUE), na.rm=TRUE)
#>     variable value
#>  1:       Q1   182
#>  2:       Q1   640
#>  3:       Q2   142
#>  4:       Q2   381
#>  5:       Q3   120
#>  6:       Q3   192
#>  7:       Q4    73
#>  8:       Q4    62
#>  9:       Q4    84
#> 10:       Q5    51
#> 11:       Q5    42
#> 12:       Q5    91
#> 13:       Q6    67
#> 14:       Q6    33
#> 15:       Q6    77
#> 16:       Q7    38
#> 17:       Q7    46
#> 18:       Q7    56
#> 19:       Q8  1820
#> 20:       Q9  2114
1 голос
/ 22 марта 2020

Не уверен, будет ли вам полезен этот вид вывода, но вот способ сделать это.

#Put the data in a list
list_df <- list(df1, df2, df3)

#Use lapply to iterate over list
output <- lapply(list_df, function(x) {
                   #shift by one row
                   x[2:(nrow(x) + 1), ] <- x
                   #Add column name as 1st row
                   x[1, ] <- names(x)
                   #Make new column names
                   names(x) <- paste0("col", seq_along(x))
                   #return the new dataframes
                   return(x)
           }) %>%  dplyr::bind_rows()
output

#  col1 col2 col3 col4
#1   Q1   Q2   Q3 <NA>
#2  182  142  120 <NA>
#3  640  381  192 <NA>
#4   Q4   Q5   Q6   Q7
#5   73   51   67   38
#6   62   42   33   46
#7   84   91   77   56
#8   Q8   Q9 <NA> <NA>
#9 1820 2114 <NA> <NA>
...