r - R:从向量的增加部分中提取频率序列(列联表)
问题描述
我有一个包含 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] 中的 3 次、V[1:7] 中的 3 次等。
我可以用一个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 的了解仍然非常基础)。
干杯!
解决方案
以 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
: 这是awesome *apply
-family 的一个功能。它接受一个向量或列表,并将指定的函数应用于该向量/列表的每个元素。sapply
返回一个简单的结构,在我们的例子中是一个用于内部 sapply-call 的向量和一个用于完整调用的矩阵。
sum(V[seq_len(i)] == j)
:这里我们对逻辑向量求和,它将每个“子向量”V[1:i]
与进行比较j
。通过对一个逻辑向量求和,我们只需计算TRUE
s 的数量。
推荐阅读
- angular - 组中的自定义 ag-grid 单元格
- google-apps-script - GAS:连接到 API 时出现错误 500
- c# - 将文件上传/下载到 Google Cloud Storage 时可能出现的异常
- java - Ant+ 连接性
- java - 从 WSL 完全卸载 opendjk-11
- git - 使用 \n 作为分支名称的一部分将 mercurial 迁移到 git - “致命:预期的提交者,但没有得到”
- python - 参数化夹具问题
- apache-spark - 在 Kubernetes 上使用 Spark 启用动态分配?
- r - 如何从模块内部在闪亮的标签面板之间切换?
- python - 使用 Tensorflow Dataset map 函数检索单个图像的多个句子