将长数据帧值拆分为具有重复列的较小帧值

时间:2018-01-29 10:00:18

标签: r dataframe matrix bioinformatics

我正在使用vcfR包。我必须打破重复的col。值垂直显示输出的同一个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函数但无法获得如上所示的帧中输出。请帮助..

2 个答案:

答案 0 :(得分:0)

您可以创建列索引列表,访问列集以获取列表,然后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的评论,似乎原始数据是长格式,一列中的列号和第二列中的数据如下:

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

答案 1 :(得分:0)

这是另一种解决方案:

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))])]

希望这有帮助!