Compute projections onto the span of a vector or a model space, dot products, and vector lengths in Euclidean space.

project(x, ...)

# S4 method for formula
project(x, u = NULL, data = parent.frame(2), coefficients = TRUE, ...)

# S4 method for numeric
project(x, u = rep(1, length(x)), type = c("vector", "length", "coef"), ...)

# S4 method for matrix
project(x, u, data = parent.frame())

vlength(x, ...)

dot(u, v)

Arguments

x

a numeric vector (all functions) or a formula (only for project). Left-hand sides of formulas should be a single quantity

...

additional arguments

u

a numeric vector

data

a data frame.

coefficients

For project(y ~ x) indicates whether the projection coefficents should be returned or the projection vector.

type

one of "length" or "vector" determining the type of the returned value

v

a numeric vector

Value

project returns the projection of x onto u

(or its length if u and v are numeric vectors and type == "length")

vlength returns the length of the vector (i.e., the square root of the sum of the squares of the components)

dot returns the dot product of u and v

Details

project (preferably pronounced "pro-JECT" as in "projection") does either of two related things: (1) Given two vectors as arguments, it will project the first onto the second, returning the point in the subspace of the second that is as close as possible to the first vector. (2) Given a formula as an argument, will work very much like lm(), constructing a model matrix from the right-hand side of the formula and projecting the vector on the left-hand side onto the subspace of that model matrix.

In (2), rather than returning the projected vector, project() returns the coefficients on each of the vectors in the model matrix. UNLIKE lm(), the intercept vector is NOT included by default. If you want an intercept vector, include +1 in your formula.

See also

link{project}

Examples

x1 <- c(1,0,0); x2 <- c(1,2,3); y1 <- c(3,4,5); y2 <- rnorm(3)
# projection onto the 1 vector gives the mean vector
mean(y2)            
#> [1] -0.2657772
project(y2, 1)
#> [1] -0.2657772 -0.2657772 -0.2657772
# return the length of the vector, rather than the vector itself
project(y2, 1, type='length')
#> [1] 0.4603395
project(y1 ~ x1 + x2) -> pr; pr
#>       x1       x2 
#> 1.230769 1.769231 
# recover the projected vector 
cbind(x1,x2) %*% pr -> v; v
#>          [,1]
#> [1,] 3.000000
#> [2,] 3.538462
#> [3,] 5.307692
project( y1 ~ x1 + x2, coefficients=FALSE )
#> [1] 3.000000 3.538462 5.307692
dot( y1 - v, v ) # left over should be orthogonal to projection, so this should be ~ 0
#> [1] 1.84297e-14
if (require(mosaicData)) {
project(width~length+sex, data=KidsFeet)
}
#>   length     sexB     sexG 
#> 0.221025 3.641168 3.408651 
vlength(rep(1,4))
#> [1] 2
if (require(mosaicData)) {
m <- lm( length ~ width, data=KidsFeet )
# These should be the same
vlength( m$effects )  
vlength( KidsFeet$length)
# So should these
vlength( tail(m$effects, -2) )
sqrt(sum(resid(m)^2))
}
#> [1] 6.233426
v <- c(1,1,1); w <- c(1,2,3)
u <- v / vlength(v)  # make a unit vector
# The following should be the same:
project(w,v, type="coef") * v 
#> [1] 2 2 2
project(w,v)
#> [1] 2 2 2
# The following are equivalent
abs(dot( w, u ))
#> [1] 3.464102
vlength( project( w, u) )
#> [1] 3.464102
vlength( project( w, v) )
#> [1] 3.464102
project( w, v, type='length' )
#> [1] 3.464102