2

I have two vectors

x <- rnorm(100)
y <- rnorm(100)

I need to compute the slopes between all points(formula: y2 - y1/ x2 - x1). So I need the slope between points (x1, y1) and (x1, y2), (x1, y1) and (x1, y3)..., (x2, y2) and (y2, y3) etc. In total it will be choose(n, 2) slopes.

How to do that in R efficiently (i need to run this many times, so efficiency is really important here)

Manuel R
  • 3,976
  • 4
  • 28
  • 41

2 Answers2

4

If you need choose(n, 2) slopes between n number of (x, y) points, use

xy <- cbind(x, y)
library(RcppAlgos)
ind <- comboGeneral(nrow(xy), 2)
d <- xy[ind[, 2], ] - xy[ind[, 1], ]
slope <- d[, 2] / d[, 1]

I am not using combn function from R core. See Product between all combinations of a vector's elements for a case study.

Zheyuan Li
  • 71,365
  • 17
  • 180
  • 248
1

Using the data in the Note at the end and assuming n choose 2 slopes are wanted.

slopes <- c(combn(y, 2, diff) / combn(x, 2, diff))
slopes
## [1] -3.7970202 -1.4062612 -3.8066222 -3.1325626 -0.9648338 -3.8171698
## [7] -2.5220191 -0.3885287 -0.5732387  4.1033272

These are the slopes of these pairs respectively:

nms <- combn(n, 2, paste, collapse = ":")
nms
## [1] "1:2" "1:3" "1:4" "1:5" "2:3" "2:4" "2:5" "3:4" "3:5" "4:5"

all.equal(slopes, slopes2[order(nms2)])

ADDED

If that is not fast enough try combnPrim from gRBase (in Bioconductor) instead:

library(gRBase)

xx <- combnPrim(x, 2)
yy <- combnPrim(y, 2)
slopes2 <- (yy[2, ] - yy[1, ]) / (xx[2, ] - xx[1, ])
slopes2
## [1] -3.7970202 -1.4062612 -0.9648338 -3.8066222 -3.8171698 -0.3885287
## [7] -3.1325626 -2.5220191 -0.5732387  4.1033272

nms2 <- apply(combnPrim(n, 2), 2, paste, collapse = ":")
## [1] "1:2" "1:3" "2:3" "1:4" "2:4" "3:4" "1:5" "2:5" "3:5" "4:5"

all.equal(slopes, slopes2[order(nms2)])
## [1] TRUE

Note

We use the following input:

set.seed(123)
n <- 5
x <- rnorm(n)
y <- rnorm(n)
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341