Subset out all elements with the same name of list - r

Data
I have a list of lists that looks something like this:
sublist1 <- list(power=as.matrix(c(rnorm(10)),c(rnorm)),x=rnorm(10),y=rnorm(10))
sublist2 <- list(power=as.matrix(c(rnorm(10)),c(rnorm)),x=rnorm(10),y=rnorm(10))
sublist3 <- list(power=as.matrix(c(rnorm(10)),c(rnorm)),x=rnorm(10),y=rnorm(10))
mylist = list(sublist1,sublist2,sublist3)
My goal would be to pull out only the matrices named power
I've tried
mylist_power =mylist[sapply(mylist, '[', 'Power')]
But thats not working.
Brownie point alert!!!
How can I find the mean of the newly created list of matrices named power?

mylist_power <- sapply(mylist, '[', 'power')
and some means:
sapply(mylist_power, mean) # one per matrix
sapply(mylist_power, colMeans) # for each column and each matrix
sapply(mylist_power, rowMeans) # for each row and each matrix
mean(unlist(mylist_power)) # for the whole list
Reduce(`+`, mylist_power) / length(mylist_power) # element-wise

purrr solution which can be replicated to baseR's Map
#part 1 (to return only $power of every list item)
map(mylist, ~.x$power)
[[1]]
[,1]
[1,] 0.33281918
[2,] -1.12404046
[3,] -0.70613078
[4,] -0.72754386
[5,] -1.83431439
[6,] -0.40768794
[7,] 0.02686119
[8,] 0.91162864
[9,] 1.63434648
[10,] 0.06068561
[[2]]
[,1]
[1,] -0.02256943
[2,] -0.90315486
[3,] 0.90777295
[4,] 1.16194290
[5,] -0.45795340
[6,] 0.92795667
[7,] -2.10293514
[8,] -1.67716711
[9,] 1.76565577
[10,] 0.79444742
[[3]]
[,1]
[1,] -0.36200564
[2,] -1.13955016
[3,] -0.81537133
[4,] 1.31024563
[5,] -0.25836094
[6,] 0.60626489
[7,] 0.31344822
[8,] 0.05360308
[9,] 1.12825379
[10,] -0.55813346
part-2
map(mylist, ~.x$power %>% colMeans)
[[1]]
[1] -0.1833376
[[2]]
[1] 0.03939958
[[3]]
[1] 0.02783941
To get these values in a vector instead
map_dbl(mylist, ~.x$power %>% colMeans)
[1] -0.18333763 0.03939958 0.02783941

Related

rolling function to get coeff of regression from a list of dataframes

I want to get coefficient of regression for each data frame in a list of dataframes with a rolling period but somehow I am getting very different result from what I am looking for.
I have tried the following code:
my data looks like this
library("zoo") ## for rollapply()
data <- list(mtcars,mtcars,mtcars)
fapplyFunction <- function(x){
coef(lm(mpg ~ drat, data=as.data.frame(x)))}
coef_list <- lapply(data, rollapply, 20, fapplyFunction, partial = FALSE, by.column = FALSE)
I wish to get regression result for each element for rolling windows as a list ,which I can later bind
I am new to R. Any help would be much appreciated.
Providing a data.frame as the first rollapply argument will apply FUN to every column of the data.frame separately. Operating on data from two columns simultaneously can be achieved by moving a rolling window across the the sequence of row numbers in the data.frame.
lapply(data, function(x)
rollapply(1:nrow(x), 20, function(i) coef(lm(mpg ~ drat, data = x[i, ]))))
#[[1]]
# (Intercept) drat
# [1,] -11.70889 8.981350
# [2,] -12.09923 9.124252
# [3,] -11.47530 9.015324
# [4,] -11.91551 9.124458
# [5,] -12.51405 9.094820
# [6,] -12.10843 8.994363
# [7,] -15.57941 9.937651
# [8,] -14.06719 9.511583
# [9,] -14.42693 9.684131
#[10,] -11.68393 8.789089
#[11,] -12.12158 8.954089
#[12,] -13.12850 9.243443
#[13,] -12.81957 9.095040
#
#[[2]]
# (Intercept) drat
# [1,] -11.70889 8.981350
# [2,] -12.09923 9.124252
# [3,] -11.47530 9.015324
# [4,] -11.91551 9.124458
# [5,] -12.51405 9.094820
# [6,] -12.10843 8.994363
# [7,] -15.57941 9.937651
# [8,] -14.06719 9.511583
# [9,] -14.42693 9.684131
#[10,] -11.68393 8.789089
#[11,] -12.12158 8.954089
#[12,] -13.12850 9.243443
#[13,] -12.81957 9.095040
#
#[[3]]
# (Intercept) drat
# [1,] -11.70889 8.981350
# [2,] -12.09923 9.124252
# [3,] -11.47530 9.015324
# [4,] -11.91551 9.124458
# [5,] -12.51405 9.094820
# [6,] -12.10843 8.994363
# [7,] -15.57941 9.937651
# [8,] -14.06719 9.511583
# [9,] -14.42693 9.684131
#[10,] -11.68393 8.789089
#[11,] -12.12158 8.954089
#[12,] -13.12850 9.243443
#[13,] -12.81957 9.095040

Dot Product In purrr

How would I calculate the dot product in purrr? As a reprex, here is a simple example.
Data generation
#fake data
X <- as_tibble(list(a = rnorm(10,0,1),
b = rnorm(10,10,1),
c = rnorm(10,100,1)))
z <- c(1,0,1)
#make tibble matrix
X_matrix <- X %>% as.matrix()
X_matrix
a b c
[1,] 0.01182775 9.032966 100.95322
[2,] 0.85718250 10.015310 102.30181
[3,] -0.06742915 10.535482 100.21764
[4,] -0.18236798 9.052234 99.37345
[5,] -0.32151084 10.329401 98.81186
[6,] 2.94303948 9.994800 99.93874
[7,] 0.03299169 9.079023 99.73501
[8,] 0.06518171 8.841637 99.91130
[9,] -0.71944580 10.281631 100.32533
[10,] 1.49983359 10.776108 99.35903
Calculate dot product
The dot product is sum(a*z[1] + b*z[2] + c*z[3])
X_matrix %*% z
[,1]
[1,] 100.96505
[2,] 103.15900
[3,] 100.15021
[4,] 99.19108
[5,] 98.49035
[6,] 102.88178
[7,] 99.76800
[8,] 99.97648
[9,] 99.60588
[10,] 100.85886
Ideally, I would like to add the dot product as a column to X

R - Dividing columns of matrix list by vector list

I have a list of matrices and a list of vectors, and I want to divide the columns of each matrix with the corresponding vector element.
For example, given
set.seed(230)
data <- list(cbind(c(NA, rnorm(6)),c(rnorm(6),NA)), cbind(runif(7), runif(7)))
divisors <- list(c(0.5,2), c(3,4))
I'm looking for a vectorized function that produces output that looks the same as
for(i in 1:length(data)){
for(j in 1:ncol(data[[i]])){data[[i]][,j] <- data[[i]][,j] / divisors[[i]][j]}
}
i.e.
[[1]]
[,1] [,2]
[1,] NA 0.28265752
[2,] -0.46967014 -0.07132588
[3,] 0.20253439 -0.37432527
[4,] 0.65736410 0.06630705
[5,] 0.72349294 0.67202129
[6,] 0.88532648 -0.80892508
[7,] 0.08162027 NA
[[2]]
[,1] [,2]
[1,] 0.26597435 0.18120979
[2,] 0.31213250 0.16493883
[3,] 0.19250804 0.14104145
[4,] 0.21196882 0.10172964
[5,] 0.10389773 0.04979742
[6,] 0.02754329 0.15064043
[7,] 0.25771766 0.23042586
The closest I have been able to come is
Map(`/`, data, divisors)
But that divides rows (rather than columns) of the matrix by the vector. Any help appreciated.
Transpose your matrices before and after:
lapply(Map(`/`, lapply(data, t), divisors), t)
# [[1]]
# [,1] [,2]
# [1,] NA 0.28265752
# [2,] -0.46967014 -0.07132588
# [3,] 0.20253439 -0.37432527
# [4,] 0.65736410 0.06630705
# [5,] 0.72349294 0.67202129
# [6,] 0.88532648 -0.80892508
# [7,] 0.08162027 NA
#
# [[2]]
# [,1] [,2]
# [1,] 0.26597435 0.18120979
# [2,] 0.31213250 0.16493883
# [3,] 0.19250804 0.14104145
# [4,] 0.21196882 0.10172964
# [5,] 0.10389773 0.04979742
# [6,] 0.02754329 0.15064043
# [7,] 0.25771766 0.23042586
I prefer the transpose approach above, but another option is to expand your divisor vectors into matrices of the same dimensions as in data:
div_mat = Map(matrix, data = divisors, nrow = sapply(data, nrow), ncol = 2, byrow = T)
Map("/", data, div_mat)

Matrix into another matrix with specified dimensions

I have a matrix with 2 columns, and I'd like to turn it into a matrix with specified dimensions.
> t <- matrix(rnorm(20), ncol=2, nrow=10)
[,1] [,2]
[1,] 1.4938530 1.2493088
[2,] -0.8079445 1.8715868
[3,] 0.5775695 -0.9277420
[4,] 0.4415969 2.6357908
[5,] 0.3209226 -1.1306049
[6,] 0.5109251 -0.8661100
[7,] 1.9495571 0.2092941
[8,] 0.7816373 1.1517466
[9,] 0.0300595 -0.1351532
[10,] 0.7550894 0.7778869
What I'd like to do is something like:
> tt <- matrix(t, ncol=4, nrow=5)
[,1] [,2] [3,] [4,]
[1,] 1.4938530 1.2493088 -0.8079445 1.8715868
[2,] 0.5775695 -0.9277420 0.4415969 2.6357908
[3,] etc.
I tried to do things with modulo but my head hurts too much for me to try even one more minute.
You can transpose your first matrix, so that data is stored in the order you want, and then fill the second matrix by row:
tt <- matrix(t(t), ncol=4, nrow=5, byrow = T)
t
# [,1] [,2]
# [1,] -1.4162465950 0.01532476
# [2,] -0.2366332875 -0.04024386
# [3,] 0.5146631983 -0.34720239
# [4,] 1.9243922633 -0.24016160
# [5,] 1.6161165230 0.63187438
# [6,] -0.3558181508 -0.73199138
# [7,] 0.7459405376 0.01934826
# [8,] -1.0428581093 -2.04422042
# [9,] 0.0003166344 0.98973993
#[10,] 0.6390745275 -0.65584930
tt
# [,1] [,2] [,3] [,4]
# [1,] -1.4162465950 0.01532476 -0.2366333 -0.04024386
# [2,] 0.5146631983 -0.34720239 1.9243923 -0.24016160
# [3,] 1.6161165230 0.63187438 -0.3558182 -0.73199138
# [4,] 0.7459405376 0.01934826 -1.0428581 -2.04422042
# [5,] 0.0003166344 0.98973993 0.6390745 -0.65584930
When you work with matrix in R, you can think of it as a vector with data stored column by column. So extracting data by row from a matrix is not as straight forward as extracting by column which is essentially how data is stored. After transposing the first matrix, the data will be stored in an order you want to extract and then fill the second matrix by row would be straight forward.

How to Set Initial Value For Creating An Index Of Returns With cumprod() in R?

I have a series of returns over some period, let's say daily returns:
> Z <-cbind(rnorm(10)*.01)
> Z
[,1]
[1,] -0.0095401182
[2,] 0.0119037893
[3,] 0.0001539471
[4,] -0.0087361367
[5,] -0.0127281577
[6,] -0.0031177198
[7,] -0.0041689219
[8,] -0.0066547279
[9,] 0.0156863175
[10,] -0.0126733237
Next, I create an investment index with cumprod() that represents the return on an initial $1 investment based on return series Z:
> ZZ <-cbind((cumprod(1+Z)*1))
> ZZ
[,1]
[1,] 0.9904599
[2,] 1.0022501
[3,] 1.0024044
[4,] 0.9936473
[5,] 0.9810000
[6,] 0.9779415
[7,] 0.9738645
[8,] 0.9673837
[9,] 0.9825584
[10,] 0.9701061
How do I edit the code for creating index ZZ so that the resulting output shows an initial value of 1.00?
Make the first return zero:
cumprod(1+c(0,rnorm(10)*.01))
Or divide all elements by the first value:
ZZ <- ZZ/ZZ[1,1]
The most direct way is to just add a 1 at the start of ZZ:
ZZ <- cbind(c(1, cumprod(1+Z)))

Resources