我正在尝试编写一个循环,该循环确定哪个单元格具有最大的值,并选择具有高中或低字符串的结果作为该单元格。这是要试用的数据。
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 becasue I have multiple coloumns in the original dataset.
return(scored.thetas.1)
}
}
> assign.levels(data)
[1] "Medium"
有什么想法吗?
谢谢!
答案 0 :(得分:2)
以下是您可能更喜欢的矢量化解决方案:
colnames(data)[apply(data, 1, which.max)]
# [1] "Medium" "High" "Low" "High" "Low" "Medium"
这是您尝试的一种简洁形式:apply
的{{1}}的每一行(维度which.max
)1
函数并获得相应的列名。
根据您的尝试,这是一个更正的版本:
data
关于您的尝试,有几件事需要提及: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"
进行迭代,而i in nrow(data)
只是一个数字。因此,基本上,您只查看最后一行; 2)您一直在每次迭代中重新定义相同的变量nrow(data)
(在这种情况下,只有一次迭代,但是趋势很差); 3)循环不是函数,您不需要从中返回任何内容,而是您很可能想将新获得的值存储在某个地方。
相比之下,请注意,首先我定义了一个长度为scored.thetas.1
的空向量scored.thetas.1
。然后,我遍历所有行(nrow(data)
)并将每个行/迭代的值存储到1:nrow(data)
。
答案 1 :(得分:2)
这应该很快
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)