R 分组数据中的性能问题
Performance Issue in R grouping data
我想做什么:
1- 将文件内容读入矩阵(有两个 features/columns:ID 和 Text)
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
)
如前所述,最大的问题是性能:我目前使用的方式需要花费很多时间。有没有类似聚合或应用的解决方案?
这是一种使用 aggregate
使用 paste
和 collapse=" " 的方法,正如@alexis-laz 所建议的:
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 会自动执行强制转换。将强制转换显式化似乎是一种很好的编程习惯。
我想做什么: 1- 将文件内容读入矩阵(有两个 features/columns:ID 和 Text) 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
)
如前所述,最大的问题是性能:我目前使用的方式需要花费很多时间。有没有类似聚合或应用的解决方案?
这是一种使用 aggregate
使用 paste
和 collapse=" " 的方法,正如@alexis-laz 所建议的:
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 会自动执行强制转换。将强制转换显式化似乎是一种很好的编程习惯。