在 R 中迭代条件和
Iterating conditional sums in R
我有一系列包含 1 和 0 的二维数值矩阵。 (所以我想它们也可以被视为逻辑数组。)我希望能够为此类数组做的是生成一个向量,其长度为数组的一维长度(列数)。对于数组中的每一列,它将包含条目为 1 的行的行总和。
这是我对单列的看法:
#Generate sample data
dataset<-matrix(sample(0:1, size=190, replace=TRUE), nrow=19, ncol=10)
#Calculate row sums
scores<-rowSums(dataset)
#calculate desired statistic for column 1
M1_1 <- sum(scores[which (dataset[,1]==1)])
#calculate same statistic for column 2
M1_2 <- sum(scores[which (dataset[,2]==1)])
显然,我不想写 M1_1、M1_2、...、M1_n,而是想定义 M1_X 来遍历每一列。我怀疑这是一件非常简单的事情,但一直无法弄清楚如何去做。任何指导将不胜感激。
我们可以用 sapply
循环并得到 sum
as.vector(sapply(split(dataset, col(dataset)), function(x) sum(scores[x==1])))
#[1] 56 47 50 53 55 48 75 67 40 55
或使用apply
apply(dataset, 2, function(x) sum(scores[x==1]))
#[1] 56 47 50 53 55 48 75 67 40 55
或者矢量化方法是复制 'scores' 并将其与 'dataset' 相乘,而不使用任何回收(这有时很危险)
colSums(scores[row(dataset)]*dataset)
#[1] 56 47 50 53 55 48 75 67 40 55
或者另一个直观的选择是 sweep
colSums(sweep(dataset, 1, scores, FUN = "*"))
#[1] 56 47 50 53 55 48 75 67 40 55
基于 OP 的 post、
M1_1
#[1] 56
M1_2
#[1] 47
或者正如@user20650 评论的那样,一个简洁的选项是crossprod
crossprod(scores, dataset)
或者在不同的步骤中甚至不计算 'scores'
rowSums(crossprod(dataset))
#[1] 56 47 50 53 55 48 75 67 40 55
我们可以将 0 和 1 的矩阵与相应的分数相乘,然后按列求和
colSums(dataset * scores)
#[1] 44 58 50 53 42 60 43 46 55 45
矩阵乘法也可以工作(可用种子 123 重现):
as.numeric(matrix(scores, nrow=1) %*% dataset)
# [1] 53 72 16 51 43 49 51 49 30 66
我有一系列包含 1 和 0 的二维数值矩阵。 (所以我想它们也可以被视为逻辑数组。)我希望能够为此类数组做的是生成一个向量,其长度为数组的一维长度(列数)。对于数组中的每一列,它将包含条目为 1 的行的行总和。
这是我对单列的看法:
#Generate sample data
dataset<-matrix(sample(0:1, size=190, replace=TRUE), nrow=19, ncol=10)
#Calculate row sums
scores<-rowSums(dataset)
#calculate desired statistic for column 1
M1_1 <- sum(scores[which (dataset[,1]==1)])
#calculate same statistic for column 2
M1_2 <- sum(scores[which (dataset[,2]==1)])
显然,我不想写 M1_1、M1_2、...、M1_n,而是想定义 M1_X 来遍历每一列。我怀疑这是一件非常简单的事情,但一直无法弄清楚如何去做。任何指导将不胜感激。
我们可以用 sapply
循环并得到 sum
as.vector(sapply(split(dataset, col(dataset)), function(x) sum(scores[x==1])))
#[1] 56 47 50 53 55 48 75 67 40 55
或使用apply
apply(dataset, 2, function(x) sum(scores[x==1]))
#[1] 56 47 50 53 55 48 75 67 40 55
或者矢量化方法是复制 'scores' 并将其与 'dataset' 相乘,而不使用任何回收(这有时很危险)
colSums(scores[row(dataset)]*dataset)
#[1] 56 47 50 53 55 48 75 67 40 55
或者另一个直观的选择是 sweep
colSums(sweep(dataset, 1, scores, FUN = "*"))
#[1] 56 47 50 53 55 48 75 67 40 55
基于 OP 的 post、
M1_1
#[1] 56
M1_2
#[1] 47
或者正如@user20650 评论的那样,一个简洁的选项是crossprod
crossprod(scores, dataset)
或者在不同的步骤中甚至不计算 'scores'
rowSums(crossprod(dataset))
#[1] 56 47 50 53 55 48 75 67 40 55
我们可以将 0 和 1 的矩阵与相应的分数相乘,然后按列求和
colSums(dataset * scores)
#[1] 44 58 50 53 42 60 43 46 55 45
矩阵乘法也可以工作(可用种子 123 重现):
as.numeric(matrix(scores, nrow=1) %*% dataset)
# [1] 53 72 16 51 43 49 51 49 30 66