代码之家  ›  专栏  ›  技术社区  ›  Vincent

R中的迭代条件和

  •  2
  • Vincent  · 技术社区  · 8 年前

    我有一系列由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来迭代每一列。我怀疑这是一件非常简单的事情,但我还没有弄清楚怎么做。如有任何指导,将不胜感激。

    3 回复  |  直到 8 年前
        1
  •  2
  •   akrun    8 年前

    我们可以循环使用 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
    

    或者,矢量化方法是复制“分数”并将其与“数据集”相乘,而不使用任何循环(有时可能很危险)

    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的帖子,

    M1_1
    #[1] 56
    M1_2
    #[1] 47
    

    或者,正如@user20650所评论的,一个简洁的选项是 crossprod

    crossprod(scores, dataset)
    

    或者甚至不用在不同的步骤中计算“分数”

    rowSums(crossprod(dataset))
    #[1] 56 47 50 53 55 48 75 67 40 55
    
        2
  •  2
  •   Ronak Shah    8 年前

    我们可以将0和1的矩阵与相应的分数相乘,然后按列求和

    colSums(dataset * scores)
    
    #[1] 44 58 50 53 42 60 43 46 55 45
    
        3
  •  1
  •   Sandipan Dey    8 年前

    矩阵乘法也将工作(可使用种子123复制):

    as.numeric(matrix(scores, nrow=1) %*% dataset)
    # [1] 53 72 16 51 43 49 51 49 30 66