【问题标题】:Performance Issue in R grouping dataR分组数据中的性能问题
【发布时间】:2016-06-21 12:59:53
【问题描述】:

我想要做什么: 1- 将文件内容读入矩阵(具有两个特征/列:ID 和文本) 2- 折叠具有相同 ID 的行,或者,如果不可能,使用折叠的数据创建一个新矩阵 3- 在 wd 中输出一个 .txt 文件,其中 ID 为名称,文本为内容

这是我所做的:

#set working directory and get file_list
myvar <- matrix(0,nrow=0,ncol=2)
colnames(myvar) <- c("PID","Seq")

for(file in file_list)
{
    print(file)
    Mymatrix <- as.matrix(read.table(file))

    for(i in 1:length(Mymatrix[,1]))
    {
        if(Mymatrix[i,1] %in% myvar[,1])
        {
            myvar[which(myvar[,1] == Mymatrix[i,1]) ,2] <- paste(myvar[which(myvar[,1] == Mymatrix[i,1]),2],Mymatrix[i,2])
        }else{
            myvar <- rbind(myvar,c(Mymatrix[i,1],Mymatrix[i,2]))
        }
    }
}

性能有问题,请参见此处的 profvis 输出:

这是一个可重现的代码:

#Input:
a <- matrix(0,ncol=2, nrow=0)
colnames(a) <- c("id","text")

#possible data in the matrix after reading one file
a <- rbind(a,c(1,"4 5 7 7 8 1"))
a <- rbind(a,c(1,"5 5 1 3 7 5 1"))
a <- rbind(a,c(7,"5 5 1 3 7 5 1"))
a <- rbind(a,c(5,"1 3 2 25 5 1 3 7 5 1"))

#expected output after processing

   > a
     id  text                       
[1,] "1" "4 5 7 7 8 1 5 5 1 3 7 5 1"
[2,] "7" "5 5 1 3 7 5 1"            
[3,] "5" "1 3 2 25 5 1 3 7 5 1"  

注意:折叠行后的文本顺序保持不变:(4 5 7 7 8 1 后跟5 5 1 3 7 5 1 for ID=1

如前所述,最大的问题是性能:我目前的做法需要很多时间。有没有类似聚合或应用的解决方案?

【问题讨论】:

  • this general QA;看来您需要以id 为组申请paste(text, collapse = " ")

标签: r performance loops grouping paste


【解决方案1】:

这是@alexis-laz 建议的使用paste 和collapse=" " 的方法:

convert matrix to data.frame and aggregate by id
dfAgg <- aggregate(text ~ id, data=data.frame(a), FUN=paste, collapse=" ")

# coerce dfAgg to matrix
as.matrix(dfAgg)
     id  text                       
[1,] "1" "4 5 7 7 8 1 5 5 1 3 7 5 1"
[2,] "5" "1 3 2 25 5 1 3 7 5 1"     
[3,] "7" "5 5 1 3 7 5 1"

请注意,在此示例中不需要使用 as.data.frame,因为 R 会自动执行强制转换。明确强制转换似乎是一种很好的编程习惯。

【讨论】:

  • 我猜聚合不接受矩阵作为输入,这就是你使用 data=data.frame(a) 的原因?我会尝试一下,看看它是否会提高性能。
  • 我从来没有在矩阵上使用过aggregate,但只是试了一下,效果很好。
  • 一个问题是您正在循环中增长一个对象。这往往会对性能产生很大影响,因为 R 必须在每次迭代中重复地将对象复制到新位置,以便添加额外的行(或列或元素)。使用循环时,最好用零或空字符串预先分配对象,然后将其填充。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多