【问题标题】:Split long dataframe values into smaller frame values having repeated columns [duplicate]将长数据帧值拆分为具有重复列的较小帧值[重复]
【发布时间】:2018-01-29 10:00:17
【问题描述】:

我正在使用 vcfR 包。我必须打破重复的col。值到相同的列垂直显示输出。

例如:

Sample Chr p-value AF MQ   Sample Chr p-value AF MQ   Sample Chr p-value AF MQ    
A1      1  0.0533  30 40     A1    1  0.0633  35 45    A1     2  0.0753  35 45

我正在尝试获取输出,

Sample    Chr    p-value    AF     MQ
A1         1     0.0533     30     40  
A1         1     0.0633     35     45  
A1         2     0.0753     35     45

我正在尝试使用 groupby 函数、sapply 函数,但无法获得如上图所示的输出。请帮忙..

【问题讨论】:

  • 你能用dput发布样本数据吗?
  • 这是私人数据。我有一个很长的数据集,其中每个字段都包含很多参数。我分离了参数并将它们转置在一个矩阵中。现在我必须将该矩阵制作成较小的框架,其中将出现很少的列及其值。如果 col 重复,那么它的对应值将在相应的 col 下拆分,但 col 标题不会出现。正如示例中提到的,正是我需要的输出。
  • 这似乎是一个很宽的data.frame,不是很长?
  • 是的,它很宽,包含重复的 cols 及其值。我必须将各个列的值放在列名下,以防止它们重复..
  • 如果您可以向我们展示产生您的输出的 vcfR 代码,可能会有更好的方法。

标签: r dataframe matrix bioinformatics


【解决方案1】:

这是一个替代解决方案:

df = read.table(text='Sample Chr p-value AF MQ   Sample Chr p-value AF MQ   Sample Chr p-value AF MQ    
A1      1  0.0533  30 40     A1    1  0.0633  35 45    A1     2  0.0753  35 45',header=T,check.names=F)

library(data.table)
group = ave(seq(ncol(df)), colnames(df), FUN = seq_along)
rbindlist(lapply(seq(max(group)), function(x) {df[,which(group==x)]}),fill=T)

输出:

   Sample Chr p-value AF MQ
1:     A1   1  0.0533 30 40
2:     A1   1  0.0633 35 45
3:     A1   2  0.0753 35 45

请注意,这要求每个组中没有不重复的列。如果有,您应该删除列,例如 df = df[, colnames(df) %in% unique(colnames(df)[duplicated(colnames(df))])]

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    您可以创建列索引列表,访问列集以获取列表,然后 rbind 列表中的元素

    numCols <- unique(diff(which(colnames(df)=="Sample")))
    indices <- split(seq_len(ncol(df)), ceiling(seq_len(ncol(df))/numCols))
    do.call(rbind, lapply(indices, function(x) {
        df[,x]      
    }))
    

    数据:

    df <- read.table(text="Sample Chr p-value AF MQ   Sample Chr p-value AF MQ   Sample Chr p-value AF MQ    
    A1      1  0.0533  30 40     A1    1  0.0633  35 45    A1     2  0.0753  35 45", 
        header=TRUE,
        check.names=FALSE)
    

    基于 OP 的 cmets,原始数据似乎是长格式,其中一列中的 colnames 和第二列中的数据如下:

    df2 <- data.frame(V1=c("Sample","Chr","p-value","AF","MQ","Sample","Chr","p-value","AF","MQ"),
        V2=c("A1","1","0.0533","30","40","A1","1","0.0633","35","45"))
    

    我们可以通过如下方式拆分行来做类似的事情,然后 rbind 结果

    do.call(rbind, lapply(split(df2$V2, cumsum(df2$V1=="Sample")), t))
    

    【讨论】:

    • 谢谢,但这里我展示了 5 列。我有更多的 cols 假设 >50/60 .. 这个 cols 是动态的,它会随着每个数据集而改变。在这种情况下,我将如何划分?
    • 你的意思是我们如何获得列数而不是硬编码为 5? unique(diff(which(colnames(df)=="Sample"))) 之类的东西?
    • 在宽 data.frame 中,我已经有了 col 名称及其值。它直接从数据集中读取(预处理),直到现在我得到的最终输出是..假设在 V1 中我有所有的列名,而 V2 我有所有的值。它们很宽,因为我使用了转置函数。现在我必须拆分它们,如 eg.. 所示,V1 将具有 col 名称而不重复 col 名称(如 eg),V2 将包含 o/p。
    • 所以你想从长宽格式转换?查看reshape::dcastdata.table::dcast.data.tabletidyr::spread。你真的需要更新你的问题。
    猜你喜欢
    • 2017-12-08
    • 1970-01-01
    • 2022-01-24
    • 2020-05-01
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 2021-09-19
    • 2018-07-14
    相关资源
    最近更新 更多