我正在尝试编写一个输入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中)并且不使用循环?
答案 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