【问题标题】:Filling up a matrix with computed values of another matrix用另一个矩阵的计算值填充一个矩阵
【发布时间】:2014-11-23 13:30:09
【问题描述】:

我没有在其他帖子中找到答案,如果他们处理类似的主题,我也不理解他们,因为我对 R 和一般编程都比较陌生。我正在使用以下调查输出 X(摘录):

A1B1         A1B2       A1B3          A1B4          A2B1          A2B2        A2B3      ...
-0.37014356  1.08841141 -0.126574243 -0.59169360  1.682673457 -0.427706432 -0.76091938  ...
3.03017573  1.39812421  0.243516558 -4.67181650 -0.378640756  2.039940436 -0.40785893   ...
3.50183121  1.51249433 -0.775449944 -4.23887560 -0.456911873  0.431838943  0.91108052   ...

...

我想计算前 4 个最大范围 diff(range(X[i,n:m])) 的差异(n:m 等于 1:4),第二个 4 (5:8) 和第三个 4 (9:12) 每一行 i 的列的差异X 并将结果放入具有 i 行和 3 列的第二个矩阵中。

例如对于第一行和前 4 列,它将是 1.08841141+0.59169360=1.68010501.

为此,我创建了一个新矩阵并尝试用值填充它:

newmatrix <- matrix(0,nrow(X),3)
newmatrix[1:nrow(X),1] <- for (i in (1:nrow(X))) {diff(range(X[i,1:4]))}  
newmatrix[1:nrow(X),2] <- for (i in (1:nrow(X))) {diff(range(X[i,5:8]))}   
newmatrix[1:nrow(X),3] <- for (i in (1:nrow(X))) {diff(range(X[i,9:12]))}

我得到输出错误:

Error in newmatrix[1:nrow(RBetas), 1] <- for (i in (1:nrow(RBetas))) { : 
  number of items to replace is not a multiple of replacement length

感谢您的帮助!

【问题讨论】:

    标签: r algorithm matrix


    【解决方案1】:

    假设列块基于前两个字符,即A1A2,我们可以通过使用substr从列名中提取前两个字符并将其拆分为不同的块并使用这是split 的索引。然后,我们可以使用applyrangediff 来获得结果,或者使用pmaxpmin

      indx <- substr(colnames(df), 1,2)
    

    如果分组不是基于column names而是基于位置,这也应该有效

      indx <- (1:ncol(df)-1)%/%4 +1
    
    
      res1 <- sapply(split(seq_len(ncol(df)), indx),
                   function(i) do.call(pmax,df[,i, drop=FALSE])-
                                     do.call(pmin, df[,i, drop=FALSE]))
    

    或者

     res2 <- sapply(split(seq_len(ncol(df)), indx),
                function(i) apply(df[,i, drop=FALSE], 1,
                              function(x) diff(range(x))) )
    
    
    
     identical(res1, res2)
     #[1] TRUE
     res1
     #        A1       A2
     #[1,] 1.680105 2.443593
     #[2,] 7.701992 2.447799
     #[3,] 7.740707 1.367992
    

    或者使用你的代码

     newmatrix <- matrix(0, nrow(df), 2) #here the example dataset is only 7 columns
     for(i in (1:nrow(df))) newmatrix[i,1] <-  diff(range(df[i,1:4]))
     for(i in (1:nrow(df))) newmatrix[i,2] <-  diff(range(df[i,5:7]))
     newmatrix
     #    [,1]     [,2]
     #[1,] 1.680105 2.443593
     #[2,] 7.701992 2.447799
     #[3,] 7.740707 1.367992
    

    如果你有很多列块,你可以试试双for循环

     lst <- split(seq_len(ncol(df)), indx) #keep the columns to group in a `list`
     newmatrix <- matrix(0, nrow(df), 2) #he
     for(i in 1:nrow(df)){
     for(j in seq_along(lst)){
       newmatrix[i,j] <- diff(range(df[i, lst[[j]]]))
      }
     }
    
    newmatrix
    #      [,1]     [,2]
    #[1,] 1.680105 2.443593
    #[2,] 7.701992 2.447799
    #[3,] 7.740707 1.367992
    

    数据

    df <- structure(list(A1B1 = c(-0.37014356, 3.03017573, 3.50183121), 
    A1B2 = c(1.08841141, 1.39812421, 1.51249433), A1B3 = c(-0.126574243, 
    0.243516558, -0.775449944), A1B4 = c(-0.5916936, -4.6718165, 
    -4.2388756), A2B1 = c(1.682673457, -0.378640756, -0.456911873
    ), A2B2 = c(-0.427706432, 2.039940436, 0.431838943), A2B3 = c(-0.76091938, 
    -0.40785893, 0.91108052)), .Names = c("A1B1", "A1B2", "A1B3", 
    "A1B4", "A2B1", "A2B2", "A2B3"), class = "data.frame", row.names = c(NA, 
    -3L))
    

    【讨论】:

    • 完美,谢谢akrun,你解决了我所有的问题! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多