R中单行中矩阵内的多次替换

Meg*_*ron 3 r matrix

有没有办法在一行中进行以下更换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
Run Code Online (Sandbox Code Playgroud)

我想知道ifelse()函数是否可以容纳这个,在if <threshold然后是0的意义上,否则为1

Ric*_*ven 7

由于您需要1和0的向量,因此您可以反转条件,将逻辑值转换为整数,并创建具有相同尺寸的新矩阵m.

matrix(as.integer(m >= threshold), nrow(m))
Run Code Online (Sandbox Code Playgroud)

您也可以只更改矩阵的模式.通常更改模式将在两行中完成,但您可以在一行中完成

`mode<-`(m >= threshold, "integer")
Run Code Online (Sandbox Code Playgroud)

另外,正如@nicola指出的那样,快速而肮脏的方法是

(m >= threshold) + 0L
Run Code Online (Sandbox Code Playgroud)

通过添加零整数,我们将整个矩阵强制转换为整数.

其他几个(感谢@Frank):

+(m >= threshold)
m[] <- m >= threshold
Run Code Online (Sandbox Code Playgroud)

所以基本上,是的.所有这些都在一行中执行任务,我几乎可以保证它们都快于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
Run Code Online (Sandbox Code Playgroud)

为了完整起见,这里是使用替换方法的基准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
Run Code Online (Sandbox Code Playgroud)

  • @nicola如果你满足于晦涩的强制,不妨只做`+(m> = threshold)` (2认同)
  • @Megatron我最好应力,只是`M> = threshold`应该足够,因为TRUE;和`FALSE`内部仅有1和0,并且可以在基本上任何实例原样使用. (2认同)