【问题标题】:Looping through each row and each column at minimum computational time以最短的计算时间遍历每一行和每一列
【发布时间】:2020-04-10 09:17:06
【问题描述】:

我有一个包含 79003 行和 97 列的数据集。我的数据集如下所示:

col1    col2          1  2         3          4         5        6        7        8         
str_11  str_44 0.2064191 0 0.6061358 0.92798677 2.7899374 1.098612 1.395511 0.000000 
str_11  str_22 0.9044563 0 1.7917595 0.00000000 1.1412787 1.504077 1.008228 0.000000 
str_11  str_18 0.8266786 0 0.5389965 0.81676114 0.2787134 0.000000 3.295837 0.000000 
str_11  str_1 0.8176492 0 5.0673306 4.45461768 0.8664189 6.549293 1.686399 2.079442 

我正在尝试遍历每一行和每一列。我想按列计算最小值和最大值并进行以下计算:

for (i in 1:nrow(log_trans2)){
    for (j in 3:ncol(log_trans2)){
        log_trans2[i, j] = log_trans2[i, ..j] -
          min(log_trans2[i, 3:ncol(log_trans2)]) / 
          (max(log_trans2[i, 3:ncol(log_trans2)]) - min(log_trans2[i, 3:ncol(log_trans2)]))
       }}

我在收到错误后添加了 ..j

"[.data.table(log_trans2, i, j) 中的错误:j(第二个参数 inside [...]) 是单个符号,但未找到列名“j”。 也许您打算使用 DT[, ..j]。与 data.frame 的区别是 在FAQ 1.1中经过深思熟虑和解释

.

但它需要更多的执行时间(比如几个小时)。如何减少使用 foreach 或 apply 函数的时间?

公式:

=(r-min(col))/(max(col)-min(col))

预期的结果是

    col1    col2    1   2   3   4   5   6   7   8
   Str_11   Str_44  0.029847796820572   0   0.080259104746805   0.11295123566895    0.405795371744574   0.138441206009843   0.167481921848205   0
   Str_11   Str_22  0.130782597207229   0   0.237248831160936   0   0.165998575836442   0.189535736027761   0.121002270272179   0
   Str_11   Str_18  0.119536094709514   0   0.071369116220582   0.099413248590107   0.040538762756246   0   0.39554907557078    0
   Str_11   Str_1   0.118230460268521   0   0.670970792433184   0.54220015449667    0.126020313332003   0.825306647460321   0.202392768285567   0.251126401405454

【问题讨论】:

  • 你有一个错字,..j 在循环内,但j 是循环变量。您可能可以提高效率,使用cummincummax 进行矢量化,而不是每次迭代都计算最小值和最大值。
  • @Gregor--reinstateMonica-- 我将 j 更改为 ..j 得到以下错误:[.data.table(log_trans2, i:nrow(log_trans2), j) 中的错误:j(第二个参数inside [...]) 是单个符号,但未找到列名“j”。也许您打算使用 DT[, ..j]。与 data.frame 的这种差异是经过深思熟虑的,并在 FAQ 1.1 中进行了解释。
  • 如何获得0.029847796820572 的第一个值?该列的min0.2064191max0.9044563 所以0.2064191-(0.206419/(0.9044563-0.206419)) 返回-0.08929432 我错过了什么吗?

标签: r foreach data.table apply


【解决方案1】:

这是避免循环的一种方法:

#Exclude columns which are not required for calculation
temp <- as.matrix(df[, -c(1:2)])
#Get column-wise minimum
min_vals <- matrixStats::colMins(temp)
#Get column-wise maximum
max_vals <- matrixStats::colMaxs(temp)
#Subtract minimum value of column from each element
s1 <- sweep(temp, 2, min_vals, `-`)
#Divide it by max - min
sweep(s1, 2, (max_vals - min_vals), `/`)

【讨论】:

    【解决方案2】:

    也许您可以将下面的代码与base R 一起使用。

    这个想法是首先获取每列的范围,然后将列视为矩阵进行操作。我相信它会比使用for 循环(受益于矩阵处理)快得多,即,

    r <- apply(d,2,range)
    df[-c(1:2)] <- t((t(df[-c(1:2)]) - r[1,])/as.vector(diff(r)))
    

    这样

    > df
         ol1   col2         1   2          3         4         5         6         7 8
    1 str_11 str_44 0.0000000 NaN 0.01482649 0.2083202 1.0000000 0.1677451 0.1692960 0
    2 str_11 str_22 1.0000000 NaN 0.27664986 0.0000000 0.3434840 0.2296549 0.0000000 0
    3 str_11 str_18 0.8885766 NaN 0.00000000 0.1833516 0.0000000 0.0000000 1.0000000 0
    4 str_11  str_1 0.8756412 NaN 1.00000000 1.0000000 0.2340315 1.0000000 0.2964541 1
    

    数据

    > dput(df)
    structure(list(ol1 = structure(c(1L, 1L, 1L, 1L), .Label = "str_11", class = "factor"), 
        col2 = structure(4:1, .Label = c("str_1", "str_18", "str_22", 
        "str_44"), class = "factor"), `1` = c(0.2064191, 0.9044563, 
        0.8266786, 0.8176492), `2` = c(0L, 0L, 0L, 0L), `3` = c(0.6061358, 
        1.7917595, 0.5389965, 5.0673306), `4` = c(0.92798677, 0, 
        0.81676114, 4.45461768), `5` = c(2.7899374, 1.1412787, 0.2787134, 
        0.8664189), `6` = c(1.098612, 1.504077, 0, 6.549293), `7` = c(1.395511, 
        1.008228, 3.295837, 1.686399), `8` = c(0, 0, 0, 2.079442)), class = "data.frame", row.names = c(NA, 
    -4L))
    

    【讨论】:

      猜你喜欢
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-17
      • 2015-04-03
      • 2021-06-12
      • 2020-02-02
      • 1970-01-01
      相关资源
      最近更新 更多