【问题标题】:How to replicate the same function over the rows in a matrix如何在矩阵中的行上复制相同的函数
【发布时间】:2019-08-09 22:19:22
【问题描述】:

我正在尝试编写一个循环来确定哪个单元格的值最大,然后选择该单元格作为结果,其中包含高、中或低字符串。这是试用的数据。

data <- matrix(c(0.3000003,0.3299896,0.3700101,
                 0.3299896,0.3700101,0.3000003,
                 0.3700101,0.3000003,0.3299896,
                 0.3000003,0.3299896,0.3700101,
                 0.3299896,0.3700101,0.3000003,
                 0.3700101,0.3000003,0.3299896),6,3)
colnames(data) <- c("Low","Medium","High")
rownames(data) <- paste("case",1:6)

> data
             Low    Medium      High
case 1 0.3000003 0.3700101 0.3299896
case 2 0.3299896 0.3000003 0.3700101
case 3 0.3700101 0.3299896 0.3000003
case 4 0.3299896 0.3000003 0.3700101
case 5 0.3700101 0.3299896 0.3000003
case 6 0.3000003 0.3700101 0.3299896

我正在使用这个函数,但它似乎只计算第一行。

assign.levels <- function(data) {

  for (i in nrow(data)) {

    scored.thetas.1 <- names(which.max(data[i,1:3])) ## I wrote 1:3 here because I have multiple columns in the original dataset.
    return(scored.thetas.1)

  }
}


> assign.levels(data)
[1] "Medium"

有什么想法吗?

提前致谢!

【问题讨论】:

  • 我认为它实际上是从最后一行返回结果

标签: r loops


【解决方案1】:

这应该很快

colnames(data)[max.col(data)]
#[1] "Medium" "High"   "Low"    "High"   "Low"    "Medium"

这是一个小基准。

n <- 1e6
set.seed(1)
data <- matrix(runif(n * 3), ncol = 3)
colnames(data) <- c("Low","Medium","High")

library(microbenchmark)

benchmark <- microbenchmark(
  OP = assign.levels(data), # as defined in Julius's answer
  Julius = colnames(data)[apply(data, 1, which.max)],
  markus = colnames(data)[max.col(data)], times = 20
)

autoplot(benchmark)

【讨论】:

  • 感谢您的快速解决方案!真的很感激。
  • 这肯定会帮助我进行完整的模拟:)
【解决方案2】:

这是您可能更喜欢的矢量化解决方案:

colnames(data)[apply(data, 1, which.max)]
# [1] "Medium" "High"   "Low"    "High"   "Low"    "Medium"

这是您尝试的简洁版本:apply 函数 which.maxdata 的每一行(维度 1)并获得相应的列名。

就您的尝试而言,这是一个更正的版本:

assign.levels <- function(data) {
  scored.thetas.1 <- rep(NA, nrow(data))
  for (i in 1:nrow(data))
    scored.thetas.1[i] <- names(which.max(data[i, ]))
  scored.thetas.1
}
assign.levels(data)
# [1] "Medium" "High"   "Low"    "High"   "Low"    "Medium"

关于您的尝试有几点需要提及:1) 您使用i in nrow(data) 进行迭代,而nrow(data) 只是一个数字。所以基本上你只看最后一行; 2) 您在每次迭代 中不断重新定义相同的变量scored.thetas.1(在这种情况下,只有一次迭代,但趋势很糟糕); 3) 循环不是函数,您不需要从中返回任何内容,而是很可能希望将新获得的值存储在某个地方。

相比之下,请注意首先我定义了一个长度为nrow(data) 的空向量scored.thetas.1。然后我遍历所有行(1:nrow(data))并将每一行/迭代的值存储到scored.thetas.1[i]

【讨论】:

  • 感谢您对我的代码所做的努力和 cmets。很有帮助!
猜你喜欢
  • 1970-01-01
  • 2019-11-29
  • 1970-01-01
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-11
相关资源
最近更新 更多