【问题标题】:Concatenate .xlsx files with successive column names in R在 R 中连接具有连续列名的 .xlsx 文件
【发布时间】:2020-03-21 22:50:43
【问题描述】:

假设我有这样的数据框:

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 排序

提前致谢

【问题讨论】:

  • 您想要 Excel 还是 R 中的所需输出?然后你将如何处理这个输出?
  • 拜托,你能更详细地解释你的问题的背景和你的意图吗?我无法想象将整洁的数据变成“不整洁”的格式有什么好处。只是为了展示?谢谢。
  • 对,只是为了展示。我知道它似乎不连贯,因此是我的问题,但它可以直观地比较不同长度的外显子放大器池的值。然后输出将用于在 .xlsx 中进行一些小的计算

标签: r concatenation xlsx


【解决方案1】:

不确定您请求的格式在 R 中是否有意义,因为

  1. data.frame 列的所有元素必须属于同一类,因此一旦将标题行添加为行,就会强制转换为字符

  2. data.frame 的所有行都必须具有相同的长度,因此您需要使用 NA 列来修补具有较少列的 data.frames

但下面是一种解决方案,它可以为您提供一个 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 中将数字数据保持为数字的更自然的方法是“对它们进行排序”,如您所说,并且,如果您愿意,可以融化并过滤它们以删除 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

【讨论】:

    【解决方案2】:

    不确定这种输出是否对您有任何帮助,但这里有一种方法可以做到这一点。

    #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>
    

    【讨论】:

      猜你喜欢
      • 2015-07-01
      • 2021-02-01
      • 2017-09-27
      • 1970-01-01
      • 2014-09-16
      • 1970-01-01
      • 2011-04-07
      • 1970-01-01
      • 2016-09-26
      相关资源
      最近更新 更多