J. *_*sen 4 for-loop r matrix vectorization
假设我们有一个m包含3列的矩阵和一个id带有行标识的向量:
m <- matrix(c(1,1,2,1,2,3,2,2,2,3,3,4,6,7,7,
2,2,2,4,4,5,8,9,9),ncol=3,byrow=T)
# m
# [,1] [,2] [,3]
#[1,] 1 1 2
#[2,] 1 2 3
#[3,] 2 2 2
#[4,] 3 3 4
#[5,] 6 7 7
#[6,] 2 2 2
#[7,] 4 4 5
#[8,] 8 9 9
id <- c(1,2,3,4,5,1,4,5)
Run Code Online (Sandbox Code Playgroud)
什么是从提取的行的最快方法m有id?
因此,我想为每个唯一标识符提供一个向量id.就像是:
##[1] 1 1 2 2 2 2
##[2] 1 2 3
##[3] 2 2 2
##[4] 3 3 4 4 4 5
##[5] 6 7 7 8 9 9
Run Code Online (Sandbox Code Playgroud)
我的相当差的解决方案对我的目的来说太慢了:
pts_list <- list()
for (i in unique(id)){
pts_list[[i]] <- as.vector(t(m[id==i,]))
}
pts_list
Run Code Online (Sandbox Code Playgroud)
这里有一个小脚本来测试速度(这真的太丑了......):
pts_list <- list()
m2 <- cbind(m,m,m,m)
m3 <- rbind(m2,m2,m2,m2,m2,m2,m2,m2,m2,m2)
m4 <- rbind(m3,m3,m3,m3,m3,m3,m3,m3,m3,m3)
m5 <- rbind(m4,m4,m4,m4,m4,m4,m4,m4,m4,m4)
m6 <- rbind(m5,m5,m5,m5,m5,m5,m5,m5,m5,m5)
id6 <- rep(1:8000,10)
system.time(
for (i in unique(id6)){
pts_list[[i]] <- as.vector(t(m6[id6==i,]))
}
)
# user system elapsed
# 8.094 1.524 9.617
Run Code Online (Sandbox Code Playgroud)
有什么建议?
如果您不关心价值观,那么您可以这样做
split(m, id)
# $`1`
# [1] 1 2 1 2 2 2
#
# $`2`
# [1] 1 2 3
#
# $`3`
# [1] 2 2 2
#
# $`4`
# [1] 3 4 3 4 4 5
#
# $`5`
# [1] 6 8 7 9 7 9
Run Code Online (Sandbox Code Playgroud)
如果你关心,你可以把它结合起来 lapply
lapply(split(as.data.frame(m), id), function(x) c(t(x)))
# $`1`
# [1] 1 1 2 2 2 2
#
# $`2`
# [1] 1 2 3
#
# $`3`
# [1] 2 2 2
#
# $`4`
# [1] 3 3 4 4 4 5
#
# $`5`
# [1] 6 7 7 8 9 9
Run Code Online (Sandbox Code Playgroud)