有没有办法在R
的一行中进行以下替换?如果可能的话,效率会更高/更低吗?
m <- matrix(rnorm(100), ncol=10)
threshold <- 0.5
# Is there a single-line way to do the following in R
m[m < threshold] <- 0
m[m >= threshold] <- 1
我想知道ifelse()
函数是否可以容纳这个,在的意义上是否&lt;阈值然后为0,否则为1
答案 0 :(得分:7)
由于你想要一个1和0的向量,你可以反转你的条件,将逻辑值转换为整数,并创建一个与m
尺寸相同的新矩阵。
matrix(as.integer(m >= threshold), nrow(m))
您也可以更改矩阵的模式。通常更改模式将在两行中完成,但您可以使用
进行一次`mode<-`(m >= threshold, "integer")
此外,正如@nicola指出的那样,快速而肮脏的方法是
(m >= threshold) + 0L
通过添加零整数,我们将整个矩阵强制转换为整数。
其他几个人(感谢@Frank):
+(m >= threshold)
m[] <- m >= threshold
所以基本上,是的。所有这些都在一行中执行任务,我几乎可以保证它们都比ifelse()
快。
更大矩阵的某些基准测试(遗漏了替换方法):
m <- matrix(rnorm(1e7), ncol=100)
threshold <- 0.5
library(microbenchmark)
microbenchmark(
matrix = matrix(as.integer(m >= threshold), nrow(m)),
mode = `mode<-`(m >= threshold, "integer"),
plus0 = (m >= threshold) + 0L,
unary = +(m >= threshold)
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# matrix 295.9292 315.4463 351.9149 351.8144 379.9840 453.4915 100
# mode 163.2156 172.0180 208.9348 202.8014 232.4525 347.0616 100
# plus0 170.2059 177.6111 202.3536 192.3516 223.8284 294.8367 100
# unary 144.0128 150.2696 183.2914 173.4010 203.7955 382.2397 100
为了完整起见,这里是使用times = 1
替换方法的基准。
microbenchmark(
replacement = { m[] <- m >= threshold },
times = 1
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# replacement 499.4005 499.4005 499.4005 499.4005 499.4005 499.4005 1