rmatrix-multiplicationcross-product# Vectorising a cross product of vector and matrix with consecutive indices in R

Some context: I have a vector e of dimensions n×1, and a correlation matrix R of n×n. I am trying to efficiently calculate the quantity

in R, without looping. So far, I have been able to do it with a single loop, using the following code:

```
nom <- 0; denom <- 0
for(i in 1:n){
nom <- nom + e[i]*(R[i,-(1:i)]%*%e[-(1:i)])
denom <- denom + e[i]*sum(e[-(1:i)])
}
beta <- nom/denom
```

This works, and in practice my calculations should not take long because for the task at hand, n will be at most of size 11 or 12 (so an improvement will likely not make a huge difference in measured time performance). However, I am curious as to how this can be done more efficiently, since

a) R is symmetrical and the calculations only need to use the part above (or below) the main diagonal of R, and

b) I am planning to use this in some MC simulations of a large size, so any calculation time I can shave off might make a difference for the big picture.

For replication/calculation purposes, here is an example of possible numerical values:

```
e <- c(0.4972,0.0902,0.02822,0.1688,0.0149,0.0028,0.01411,0.02733,0.0151,0.0391,0.01301,0.0894)
R <- matrix(data = c(1,0.9,0.4,0.75,0.5,0.3,0.4,0.4,0.25,0.25,0.5,0.4,0.9,1,0.5,0.9,0.5,0.3,0.4,0.35,0.2,0.2,0.5,0.3,0.4,0.5,1,0.3,0.5,0.4,0.25,0.2,0.2,0.2,0.3,0.3,0.75,0.9,0.3,1,0.3,0.3,0.4,0.25,0.25,0.2,0.3,0.75,0.5,0.5,0.5,0.3,1,0.5,0.35,0.8,0.8,0.3,0.7,0.45,0.3,0.3,0.4,0.3,0.5,1,0.3,0.4,0.3,0.2,0.45,0.35,0.4,0.4,0.25,0.4,0.35,0.3,1,0.3,0.3,0.2,0.5,0.5,0.4,0.35,0.2,0.25,0.8,0.4,0.3,1,0.8,0.2,0.6,0.8,0.25,0.2,0.2,0.25,0.8,0.3,0.3,0.8,1,0.3,0.7,0.8,0.25,0.2,0.2,0.2,0.3,0.2,0.2,0.2,0.3,1,0.25,0.3,0.5,0.5,0.3,0.3,0.7,0.45,0.5,0.6,0.7,0.25,1,0.7,0.4,0.3,0.3,0.75,0.45,0.35,0.5,0.8,0.8,0.3,0.7,1), nrow = 12, ncol = 12)
```

Solution

You can do:

```
ee <- tcrossprod(e)
ee0 <- ee; diag(ee0) <- 0
sum(R*ee0)/sum(ee0)
```

For your example data:

```
> sum(R*ee0)/sum(ee0)
[1] 0.5647038
```

A little save of calculation: `sum(ee0)`

is equal to

```
sum(e)^2 - sum(e^2)
```

Here is another variant:

```
d <- diag(R)
diag(R) <- 0
sum(e*crossprod(e, R))/(sum(e)^2 - sum(e^2))
```

- How can I extract a value from a dataframe based on a range of values?
- Confidence Interval for Some (But Not All) Interaction Terms in a Polynomial Interacted with a Binary Treatment
- Avoiding crazy lines while mapping in r
- Overlay points on top of violin plot
- Add percentage labels to geom_col()
- How to place a js inside a swiper with appendTo()?
- How to make a single plot from two dataframes with ggplot2
- Error in installing "TopicModels" package in Google Colab
- Identify connected subnetworks (R-igraph)
- Adding labels to geom_col()
- Legend title in ggplot2
- R list files with multiple conditions
- R - getting count of maximum-sized sub-group when summarising at prior group_by level
- Problems when running GDC_prepare in R
- Filtering files with names starting with a specific string
- Mutate a vector within a pipe chain
- How to sum a variable by group
- Using hex code to change text color in RMarkdown PDF (R)
- How to Remove Degree and Cardinal Direction Symbols from ggplot Coordinate Axes
- rstan and brms cause R and RStudio session abort
- How to change the plot background color generated by plot(effect(...)) in grey with white grid in R？
- SQL query on arrow duckdb workflow in R
- Venn diagram with duplicated elements
- R- Filter by time closest to midnight
- Difference between rlm() and lm_robust
- Is there a way to combine sorting an rhandsontable and removing from an rhandsontable?
- Split violin plot with ggplot2
- ggbarplot top of one bar does not align with its error bar
- read file from google drive
- Placing text into stacked bar charts in ggplot