在R中添加2个没有循环的向量

时间:2016-05-25 13:33:25

标签: r

我正在尝试编写一个输入2个向量的函数,并返回一个矩阵,其中每个元素[i,j]是x [i] + y [j]

例如,让我们说x是

2 3 5 7

而且是

2 3 8

输出需要

4  5  10 5  6  11 7  8  15 9  10 15

如何使用其中一个应用函数(在R中)并且不使用循环?

5 个答案:

答案 0 :(得分:5)

您需要先使用outer()转置它来t()convert the result to a matrix row-by-row

> x <- c(2,3,5,7)
> y <- c(2,3,8)
> outer(x,y,"+")
     [,1] [,2] [,3]
[1,]    4    5   10
[2,]    5    6   11
[3,]    7    8   13
[4,]    9   10   15
> as.vector(t(outer(x,y,"+")))
 [1]  4  5 10  5  6 11  7  8 13  9 10 15

答案 1 :(得分:2)

这给出了期望的结果:

x <- c(2,3,5,7)
y <- c(2,3,8)
rep(x, each=length(y)) + y
# [1]  4  5 10  5  6 11  7  8 13  9 10 15

答案 2 :(得分:2)

<强> BENCHMARK

小规模

library(microbenchmark)

x <- c(2,3,5,7)
y <- c(2,3,8)

func_Stephan.Kolassa <- function(x, y){ as.vector(t(outer(x,y,"+"))) }
func_m0h3n <- function(x, y){as.vector(sapply(x, function(a) { sapply(y, function(b) a+b) }))}
func_jogo <- function(x, y){rep(x, each=length(y)) + y}
func_Vincent.Guillemot <- function(x, y){do.call("c", lapply(x, "+", y))}

r1=func_Stephan.Kolassa(x,y)
identical(func_m0h3n(x,y), r1)
# [1] TRUE
identical(func_jogo(x,y), r1)
# [1] TRUE
identical(func_Vincent.Guillemot(x,y), r1)
# [1] TRUE

microbenchmark(func_Stephan.Kolassa(x,y), func_m0h3n(x,y), func_jogo(x,y), func_Vincent.Guillemot(x,y))

Unit: nanoseconds
                         expr   min    lq     mean  median      uq    max neval
   func_Stephan.Kolassa(x, y)  9315  9916 11875.10 10517.0 11118.0  52582   100
             func_m0h3n(x, y) 53184 55587 59850.90 57089.5 63099.5 100958   100
              func_jogo(x, y)   601   902  1307.46  1202.0  1203.0   8414   100
 func_Vincent.Guillemot(x, y)  5409  6009  6836.19  6610.0  6911.5  17728   100

中等规模

library(microbenchmark)

set.seed(100)
x <- sample(500)
y <- sample(500)

func_Stephan.Kolassa <- function(x, y){ as.vector(t(outer(x,y,"+"))) }
func_m0h3n <- function(x, y){as.vector(sapply(x, function(a) { sapply(y, function(b) a+b) }))}
func_jogo <- function(x, y){rep(x, each=length(y)) + y}
func_Vincent.Guillemot <- function(x, y){do.call("c", lapply(x, "+", y))}

r1=func_Stephan.Kolassa(x,y)
identical(func_m0h3n(x,y), r1)
# [1] TRUE
identical(func_jogo(x,y), r1)
# [1] TRUE
identical(func_Vincent.Guillemot(x,y), r1)
# [1] TRUE

microbenchmark(func_Stephan.Kolassa(x,y), func_m0h3n(x,y), func_jogo(x,y), func_Vincent.Guillemot(x,y))

Unit: microseconds
                         expr        min         lq       mean     median         uq        max neval
   func_Stephan.Kolassa(x, y)   1494.534   1593.389   1873.291   1695.699   1787.793   4138.064   100
             func_m0h3n(x, y) 147586.916 156473.596 160685.272 159005.951 161304.842 218236.564   100
              func_jogo(x, y)   3861.932   3889.275   4544.668   3988.130   4102.308  46668.592   100
 func_Vincent.Guillemot(x, y)    926.047   1046.235   1648.450   1083.944   1173.934  43615.523   100

大规模

library(microbenchmark)

set.seed(100)
x <- sample(2000)
y <- sample(2000)

func_Stephan.Kolassa <- function(x, y){ as.vector(t(outer(x,y,"+"))) }
func_m0h3n <- function(x, y){as.vector(sapply(x, function(a) { sapply(y, function(b) a+b) }))}
func_jogo <- function(x, y){rep(x, each=length(y)) + y}
func_Vincent.Guillemot <- function(x, y){do.call("c", lapply(x, "+", y))}

r1=func_Stephan.Kolassa(x,y)
identical(func_m0h3n(x,y), r1)
# [1] TRUE
identical(func_jogo(x,y), r1)
# [1] TRUE
identical(func_Vincent.Guillemot(x,y), r1)
# [1] TRUE

microbenchmark(func_Stephan.Kolassa(x,y), func_m0h3n(x,y), func_jogo(x,y), func_Vincent.Guillemot(x,y))

Unit: milliseconds
                         expr        min         lq       mean     median         uq        max neval
   func_Stephan.Kolassa(x, y)   36.74259   43.74743   74.99681   83.46406   85.95180  136.20484   100
             func_m0h3n(x, y) 2456.30410 2520.29204 2552.30450 2543.17729 2569.69776 2716.24160   100
              func_jogo(x, y)   62.74701   63.20868   67.18512   64.66190   66.28563  117.96876   100
 func_Vincent.Guillemot(x, y)   14.35702   16.37528   30.59328   18.03522   58.94261   65.50772   100

答案 3 :(得分:1)

只是为了使用lapply

的乐趣
x <- c(2,3,5,7)
y <- c(2,3,8)
do.call("c", lapply(x, "+", y))
# [1]  4  5 10  5  6 11  7  8 13  9 10 15

答案 4 :(得分:0)

这是我的解决方案:

as.vector(sapply(x, function(a) { sapply(y, function(b) a+b) }))
# [1]  4  5 10  5  6 11  7  8 13  9 10 15