在 R 中使用 apply 对同一矩阵进行重复子集化
Repeated subsetting of the same matrix using apply in R
动机:我目前正在尝试重新考虑我的编码,例如尽可能排除 for 循环。下面的问题可以很容易地用传统的 for 循环来解决,但我想知道 R 是否提供了利用 apply-family 来简化问题的可能性。
问题:我有一个矩阵,比如 X
(n x k
矩阵)和两个起始索引和终止索引矩阵,称为 index.starts
和 index.stops
。它们的大小为 n x B
,并且对于某个整数 m
,它认为 index.stops = index.starts + m
。每对 index.starts[i,j]
和 index.stops[i,j]
都需要将 X
子集化为 X[ (index.starts[i,j]:index.stops[i,j]),]
。也就是说,他们应该 select 在其索引范围内 X
的所有行。
我可以使用应用函数之一解决这个问题吗?
Application:(对于理解我的问题不一定重要。)如果您有兴趣,这对于时间序列应用程序中包含块的引导应用程序是必需的。 X
代表原始样本。 index.starts
采样为replicate(repetitionNumber, sample.int((n-r), ceiling(n/r), replace=TRUE))
,得到index.stops
为index.stop = index.starts + m
。我最终想要的是X
行的集合。特别是,我想从 X
.
中重采样 repetitionNumber
次 m
个长度为 r
的块
示例:
#generate data
n<-100 #the size of your sample
B<-5 #the number of columns for index.starts and index.stops
#and equivalently the number of block bootstraps to sample
k<-2 #the number of variables in X
X<-matrix(rnorm(n*k), nrow=n, ncol = k)
#take a random sample of the indices 1:100 to get index.starts
r<-10 #this is the block length
#get a sample of the indices 1:(n-r), and get ceiling(n/r) of these
#(for n=100 and r=10, ceiling(n/r) = n/r = 10). Replicate this B times
index.starts<-replicate(B, sample.int((n-r), ceiling(n/r), replace=TRUE))
index.stops<-index.starts + r
#Now can I use apply-functions to extract the r subsequent rows that are
#paired in index.starts[i,j] and index.stops[i,j] for i = 1,2,...,10 = ceiling(n/r) and
#j=1,2,3,4,5=B ?
它可能比您 want/need 复杂得多,但这是第一种方法。如果这对您有任何帮助,请发表评论,我很乐意提供帮助。
我的方法使用(多个)*apply-functions。第一个 lapply "loops" 超过 1:B 的情况,它首先计算起点和终点,它们被组合成 take.rows(带有子集编号)。接下来,初始矩阵被 take.rows 子集化(并在列表中返回)。作为最后一步,对子集矩阵的每一列取标准差(作为虚拟函数)。
代码(带有大量注释)如下所示:
# you can use lapply in parallel mode if you want to speed up code...
lapply(1:B, function(i){
starts <- sample.int((n-r), ceiling(n/r), replace=TRUE)
# [1] 64 22 84 26 40 7 66 12 25 15
ends <- starts + r
take.rows <- Map(":", starts, ends)
# [[1]]
# [1] 72 73 74 75 76 77 78 79 80 81 82
# ...
res <- lapply(take.rows, function(subs) X[subs, ])
# res is now a list of 10 with the ten subsets
# [[1]]
# [,1] [,2]
# [1,] 0.2658915 -0.18265235
# [2,] 1.7397478 0.66315385
# ...
# say you want to compute something (sd in this case) you can do the following
# but better you do the computing directly in the former "lapply(take.rows...)"
res2 <- t(sapply(res, function(tmp){
apply(tmp, 2, sd)
})) # simplify into a vector/data.frame
# [,1] [,2]
# [1,] 1.2345833 1.0927203
# [2,] 1.1838110 1.0767433
# [3,] 0.9808146 1.0522117
# ...
return(res2)
})
你说的对吗direction/gives你就是答案?
动机:我目前正在尝试重新考虑我的编码,例如尽可能排除 for 循环。下面的问题可以很容易地用传统的 for 循环来解决,但我想知道 R 是否提供了利用 apply-family 来简化问题的可能性。
问题:我有一个矩阵,比如 X
(n x k
矩阵)和两个起始索引和终止索引矩阵,称为 index.starts
和 index.stops
。它们的大小为 n x B
,并且对于某个整数 m
,它认为 index.stops = index.starts + m
。每对 index.starts[i,j]
和 index.stops[i,j]
都需要将 X
子集化为 X[ (index.starts[i,j]:index.stops[i,j]),]
。也就是说,他们应该 select 在其索引范围内 X
的所有行。
我可以使用应用函数之一解决这个问题吗?
Application:(对于理解我的问题不一定重要。)如果您有兴趣,这对于时间序列应用程序中包含块的引导应用程序是必需的。 X
代表原始样本。 index.starts
采样为replicate(repetitionNumber, sample.int((n-r), ceiling(n/r), replace=TRUE))
,得到index.stops
为index.stop = index.starts + m
。我最终想要的是X
行的集合。特别是,我想从 X
.
repetitionNumber
次 m
个长度为 r
的块
示例:
#generate data
n<-100 #the size of your sample
B<-5 #the number of columns for index.starts and index.stops
#and equivalently the number of block bootstraps to sample
k<-2 #the number of variables in X
X<-matrix(rnorm(n*k), nrow=n, ncol = k)
#take a random sample of the indices 1:100 to get index.starts
r<-10 #this is the block length
#get a sample of the indices 1:(n-r), and get ceiling(n/r) of these
#(for n=100 and r=10, ceiling(n/r) = n/r = 10). Replicate this B times
index.starts<-replicate(B, sample.int((n-r), ceiling(n/r), replace=TRUE))
index.stops<-index.starts + r
#Now can I use apply-functions to extract the r subsequent rows that are
#paired in index.starts[i,j] and index.stops[i,j] for i = 1,2,...,10 = ceiling(n/r) and
#j=1,2,3,4,5=B ?
它可能比您 want/need 复杂得多,但这是第一种方法。如果这对您有任何帮助,请发表评论,我很乐意提供帮助。
我的方法使用(多个)*apply-functions。第一个 lapply "loops" 超过 1:B 的情况,它首先计算起点和终点,它们被组合成 take.rows(带有子集编号)。接下来,初始矩阵被 take.rows 子集化(并在列表中返回)。作为最后一步,对子集矩阵的每一列取标准差(作为虚拟函数)。
代码(带有大量注释)如下所示:
# you can use lapply in parallel mode if you want to speed up code...
lapply(1:B, function(i){
starts <- sample.int((n-r), ceiling(n/r), replace=TRUE)
# [1] 64 22 84 26 40 7 66 12 25 15
ends <- starts + r
take.rows <- Map(":", starts, ends)
# [[1]]
# [1] 72 73 74 75 76 77 78 79 80 81 82
# ...
res <- lapply(take.rows, function(subs) X[subs, ])
# res is now a list of 10 with the ten subsets
# [[1]]
# [,1] [,2]
# [1,] 0.2658915 -0.18265235
# [2,] 1.7397478 0.66315385
# ...
# say you want to compute something (sd in this case) you can do the following
# but better you do the computing directly in the former "lapply(take.rows...)"
res2 <- t(sapply(res, function(tmp){
apply(tmp, 2, sd)
})) # simplify into a vector/data.frame
# [,1] [,2]
# [1,] 1.2345833 1.0927203
# [2,] 1.1838110 1.0767433
# [3,] 0.9808146 1.0522117
# ...
return(res2)
})
你说的对吗direction/gives你就是答案?