我有一个带有n个元素的向量V,每个元素可以是1到N之间的整数。给定这个向量我想构造一个N×n矩阵W,其中列i包含1之间的整数频率和N出现在子向量V [1:i]中。
例如,假设N = 5且n = 7,并且V = c(3,1,4,1,2,1,4)。然后我的矩阵W将有元素
0,1,1,2,2,3,3
0,0,0,0,1,1,1
1,1,1,1,1,1,1
0,0,1,1,1,1,2
0,0,0,0,0,0,0
因为整数1(第一行)出现:V [1]中0次,V [1:2]中一次,V [1:3]中一次,V [1:4]中两次,V中两次[1:5],V [1:6]三次,V [1:7]三次等
我可以使用for
循环,例如使用table
和factor
:
N <- 5
n <- 7
V <- c(3,1,4,1,2,1,4)
W <- matrix(NA,N,n)
for(i in 1:n){
W[,i] <- as.vector(table(factor(V[1:i], levels=1:N)))
}
实际上是
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 0 1 1 2 2 3 3
[2,] 0 0 0 0 1 1 1
[3,] 1 1 1 1 1 1 1
[4,] 0 0 1 1 1 1 2
[5,] 0 0 0 0 0 0 0
但是我想知道是否有一些更聪明,更快速的方式不使用for循环:我的N和n大约是100或1000.
我们也欢迎任何改进上述代码的其他见解(我对R的了解仍然非常基础)。
干杯!
答案 0 :(得分:1)
基地R的一个选项是:
V <- c(3, 1, 4, 1, 2, 1, 4)
N <- 5
sapply(seq_along(V),
function(i) sapply(seq_len(N), function(j) sum(V[seq_len(i)] == j)))
# [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,] 0 1 1 2 2 3 3
# [2,] 0 0 0 0 1 1 1
# [3,] 1 1 1 1 1 1 1
# [4,] 0 0 1 1 1 1 2
# [5,] 0 0 0 0 0 0 0
工作原理
seq_along(V)
:这是1:length(V)
的包装器,即它返回一个从1到矢量V长度的向量。如果你确定,你的向量V是非空的你也可以使用1:length(V)
此处(或您的1:n
)
seq_len(N)
:与seq_along
类似,但会返回1:N
。如果你确定N是非负数,那么你也可以使用1:N
。
sapply
:这是来自真棒*apply
- 系列的功能。它采用向量或列表,并应用为此向量/列表的每个元素指定的函数。 sapply
返回一个简单的结构,在我们的例子中是内部sapply-call的向量和完整调用的矩阵。
sum(V[seq_len(i)] == j)
:这里我们总结一下逻辑向量,它比较每个子向量&#39; V[1:i]
j
TRUE
。通过对逻辑向量求和,我们只计算mov
s的数量。