【问题标题】:Optimize Apply() While() in R在 R 中优化 Apply() While()
【发布时间】:2017-07-06 22:02:34
【问题描述】:

以下数据用于进行比较分析。我使用apply()while() 编写了代码,尽管它按预期工作,但我还没有成功地进一步优化它。在较大的数据集中,当前运行时间超过几个小时。

以下是小示例数据集:

data_1

A B C D
2 1 3 2.5

data_2

P Q R S
3 2 4 5.5

数据

 A   B   C   D
1.0 0.5 1.3 1.5
1.5 1.2 5.5 3.5
1.1 0.5 1.3 1.5
1.5 1.2 5.5 3.5
1.5 1.2 5.5 3.5
1.1 0.5 1.3 1.5
1.5 1.2 5.5 3.5
1.0 0.5 1.3 1.5

代码

# Row counter 
rowLine <<- 0

# Set current column to first one
columnLine <<- 1

# Preserve column header and dimensions for final data
finalData <- Data

# Find recursively
findThreshold <- function () {

  if ( columnLine <= ncol(Data) ){

    # Initialize row navigation to zero
    rowLine  <<- 1

    # Navigate through rows
    while (rowLine <= nrow(Data)){

      # If outside threshold
      if ( (Data[rowLine, columnLine] < data_1[columnLine]) |
           (Data[rowLine, columnLine] > data_2[columnLine])){

        finalData[rowLine, columnLine] <<- 1

      } else {

        finalData[rowLine, columnLine] <<- 0

      }

      # Increment row counter
      rowLine <<- rowLine + 1

    }
  }

  # Increment column counter
  columnLine <<- columnLine + 1

}

# Apply
apply(Data, 2, function(x) findThreshold())

我也明白使用&lt;&lt;-loops 和像apply() 这样的递归分析一起使用是一个很大的问题。

请建议我如何进一步改进此逻辑,谢谢。

【问题讨论】:

  • 你能解释一下你的代码试图做什么吗?我可以运行该函数,但我不确定输出与什么相关。
  • @thelatemail - 将输出存储在finalData 中,将Data 中的每个元素与较低阈值data_1 和较高阈值data_2 进行比较,结果为真假。
  • finalData &lt;- sapply(1:4, function(col) (Data[,col] &lt; data_1[,col] | Data[,col] &gt; data_2[,col]))怎么样
  • 第 3 行和第 8 行仍然出错
  • 只嵌入as.integer()

标签: r algorithm optimization packages


【解决方案1】:

听起来像是一个简单的Map 练习:

data.frame(Map(function(d,l,h) d < l | d > h, Data, data_1, data_2))
#     A     B    C     D
#1 TRUE  TRUE TRUE  TRUE
#2 TRUE FALSE TRUE FALSE
#3 TRUE  TRUE TRUE  TRUE
#4 TRUE FALSE TRUE FALSE
#5 TRUE FALSE TRUE FALSE
#6 TRUE  TRUE TRUE  TRUE
#7 TRUE FALSE TRUE FALSE
#8 TRUE  TRUE TRUE  TRUE

如果您想要 0/1 输出,只需将逻辑比较包装在 as.integer 中即可:

data.frame(Map(function(d,l,h) as.integer(d < l | d > h), Data, data_1, data_2))

如果您的数据是matrix 对象开始,您可以使用sweep

sweep(Data, 2, data_1, FUN=`<`) | sweep(Data, 2, data_2, FUN=`>`)
#        A     B    C     D
#[1,] TRUE  TRUE TRUE  TRUE
#[2,] TRUE FALSE TRUE FALSE
#[3,] TRUE  TRUE TRUE  TRUE
#[4,] TRUE FALSE TRUE FALSE
#[5,] TRUE FALSE TRUE FALSE
#[6,] TRUE  TRUE TRUE  TRUE
#[7,] TRUE FALSE TRUE FALSE
#[8,] TRUE  TRUE TRUE  TRUE

【讨论】:

  • 感谢@thelatemail,您的解决方案也有效。我想保持输出finalData 矩阵结构类似于Data,包括列名。使用Map,它被转换为具有逻辑值的单行。这就是我做finalData &lt;- Data 的原因,为了复制矩阵结构,然后在比较后用逻辑值更新它。您能否建议这是否可以使用Map 本身来完成?我知道我的方法不是最好的。
  • @ChetanArvindPatil - Map 只返回一个列表,通过将data.frame(...) 包裹在其周围,可以将其制成与Data 相同大小的data.frame - 请参阅我的编辑。上面包括as.integer 的第二行代码将与您的finalData 相同
  • .@thelatemail - 在测试您的代码之前,我确实在Map() 周围使用了data.frame(....)。它以1xN 而不是MxN 提供输出。
  • @ChetanArvindPatil - Datamatrix 吗?我假设它和data_1/2data.frames 开始。这就是为什么一个可重复的例子很重要的原因。
  • .@thelatemail - 是的,它是matrix。这是我第二次搞砸data.framematrix 的可重复示例。 is.data.frame(Data) [1] FALSE。甚至我的真实数据集也是matrix
猜你喜欢
  • 2017-12-07
  • 1970-01-01
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 2011-04-05
  • 2018-03-01
相关资源
最近更新 更多