假设我有一个矩阵,其中行代表单个样本。我在没有替换的情况下进行采样,因此行不会包含重复的条目。
samp_frame <- 1:6
samp <- matrix(c(1,2,3,3,4,1,5,1,6),nrow=3,ncol=3)
samp
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 1
[3,] 3 1 6
我想计算包含一对值的样本数,然后将结果存储在矩阵中。例如,输出矩阵中的条目(1,2)将是值1和2一起出现在同一行中的次数。使用上面的例子,我们得到:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 1 2 1 1 1
[2,] 1 1 0 1 0 0
[3,] 2 0 2 0 1 1
[4,] 1 1 0 1 0 0
[5,] 1 0 1 0 1 0
[6,] 1 0 1 0 0 1
我写了一个函数来做这个,但它可能效率不高。所以我正在寻找有关如何改进它的建议。
pair_freq <- function(samp_frame,samp){
N <- length(samp_frame)
output <- matrix(0,nrow=N,ncol=N)
# Fill in diagonal entries
temp <- table(samp)
freq <- data.frame(id=as.numeric(rownames(temp)),
count=data.frame(temp)[,2])
for (i in 1:N){
output[i,i] <- freq[i,"count"]
}
# Fill in off-diagonal entries
for(i in 1:nrow(samp)){
current <- unique(samp[i,])
for (j in 1:(N-1)){
m <- j+1
for (k in m:N){
output[j,k] <- output[j,k] + all(c(j,k) %in% current)
output[k,j] <- output[j,k]
}
}
}
output
}
如果做得更快,我也愿意以下列格式显示频率。
X1 X2 freq
1 1 3
1 2 1
1 3 2
1 4 1
1 5 1
1 6 1
2 2 1
2 3 1
...
答案 0 :(得分:1)
这是一种方式:
is.present <- function(j)apply(samp,1,function(row)as.integer(any(row==j)))
m <- sapply(min(samp):max(samp),is.present)
t(m) %*% m
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 3 1 2 1 1 1
# [2,] 1 1 0 1 0 0
# [3,] 2 0 2 0 1 1
# [4,] 1 1 0 1 0 0
# [5,] 1 0 1 0 1 0
# [6,] 1 0 1 0 0 1
因此,您有n个样本(在您的示例中为3个),其中包含k个可能的结果(在您的示例中为1:6)。
在这种方法中,is.present(j)
创建一个长度为n
的向量,如果该行中存在数字j
,则该元素为1,否则为0。然后
m <- sapply(min(samp):max(samp),is.present)
创建一个n×k矩阵m
,其中samp中每行有一行,每个可能结果有一列,如果m[i,j] = 1
中有j
,则为i
samp的行[i,j]
。然后,
m T ×m
生成一个k×k矩阵,其中samp
元素是i
中j
和{{1}}一起出现的数字。{/ p>