R:从矢量的增加部分提取频率序列(列联表)

时间:2018-05-29 10:19:28

标签: r for-loop count frequency-distribution contingency

我有一个带有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循环,例如使用tablefactor

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的了解仍然非常基础)。

干杯!

1 个答案:

答案 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的数量。