R sum element X in list of vector - r

I just started doing some R script and I can't figure out this problem.
I got a list of vector let say
myListOfVector <- list(
c(1,2),
c(1,2),
c(1,2),
c(1,2)
)
what I want is the sum of each X element of each vector that are in my list base on the position of the element
so that if I have 3 vector that contains (a, b, c), I will get the sum of each a, each b and each c in a list or vector
I know that each vector are the same length
What I seek is something like that
result <- sum(myListOfVector)
# result must be c(4, 8)
Does anybody have an idea ?
The only way I've been able to do it is by using a loop but it take so much time that I can't resign to do it.
I tried some apply and lapply but they don't seem to work like I want it to because all I have is one vector at a time.
Precision :
The list of vector is returned by a function that I can't modify
I need an efficient solution if possible

A list of vectors of the same length can be summed with Reduce:
Reduce(`+`, myListOfVector)
Putting it in a matrix and using colSums or rowSums, as mentioned by #AnandaMahto and #JanLuba, might be faster in some cases; I'm not sure.
Side note. The example in the OP is not a list; instead, it should be constructed like
myListOfVector <- list( # ... changing c to list on this line
c(1,2),
c(1,2),
c(1,2),
c(1,2)
)

you should first convert your list to a matrix:
mymatrix=matrix(myListOfVector,ncol=2,byrow=T)
and then use colSums:
colSums(mymatrix)

Related

R: choose elements from list based on values in vector with same names

[Probably this question already has an answer here, but I didn't manage to find one, also because I have some difficulty in formulating it concisely. Suggestions for reformulating the title of the question are appreciated.]
I have
a list of matrices with different numbers of rows,
a vector of integer values with the same names as the list's,
a list of names that appear in the list and vector above,
an integer variable telling which column to choose from those matrices.
Let's construct, as a working example:
mynames <- c('a', 'c')
mylist <- list(a=matrix(1:4,2,2), b=matrix(1:6,3,2), c=matrix(1:8,4,2))
myvec <- 2:4
names(myvec) <- names(mylist)
chooseCol <- 2
I'd like to construct a vector having as elements the rows taken from myvec and column chooseCol, for the names appearing in mynames. My attempt is
sapply(mynames, function(elem){mylist[[elem]][myvec[elem], chooseCol]})
which correctly yields
a c
4 8
but I was wondering if there's a faster, base (non-tidyverse) method of doing this.
Also important or relevant: the order of the names in mylist and myvec can be different, so I can't rely on position indices.
I would use mapply -
mapply(function(x, y) x[y, chooseCol], mylist[mynames], myvec[mynames])
#a c
#4 8

R create list or matrix

If I repeat this code
x<-1:6
n<-40
M<-200
y<-replicate(M,as.numeric(table(sample(x,n,1))))
str(y)
sometimes R decide to create a matrix and sometimes it creates a list. Can you explain me the reason for that? How can I be sure that it is a matrix or a list?
If you chose M very small, for example 10, it will almost always create a matrix. If you chose M very large, for example 2000, it will create a list.
You get a list for cases when not all the numbers in x are sampled.
You can always return a list by using simplify = FALSE.
y <- replicate(M, as.numeric(table(sample(x,n,TRUE))), simplify = FALSE)
Also, you are using 1 to set replace argument. It is better to use logical argument i.e TRUE.
To return always a matrix, we can do :
sapply(y, `[`, x)
This will append NA's for values where length is unequal.
May be it will help
[https://rafalab.github.io/dsbook/r-basics.html#data-types][1]
Vectors in matrix have to be all the same type and length
Vectors in list can contain elements of different classes and length
Try this:
x<-1
y<-2:7
z<-matrix(x,y)
z<-list(x,y)
In first case you will get matrix 2 rows and 1 column because y vector is longer
In the second case you will get a list with elements of different length.
Also
str()
function is very useful. But you can find the class of object using
class()
function.

apply() function to columns of a matrix and elements of a numeric vector, respectively, in order

I have a function f(list,t) where the first argument is a list and the second one t is a number. I wanna apply f to columns of a matrix M and elements of a vector T respectively. Hence, if columns of M are (M_1,M_2,...,M_k) and T = (t_1,t_2,...,t_k), I want to get the following :
f(M_1,t_1), f(M_2,t_2), ..., f(M_k,t_k).
Is there an efficient way doing so without using for loop?
For example if
f <- function(list,x) {x %in% list}
M <- matrix(1:12,4,3)
T <- c(1,2,10)
I expect to get
TRUE FALSE TRUE
The following line applies f on each column of M and each element of T
apply(M,2,f,T)
But what I need is just the diagonal of this output, so I want a way to avoid extra computations.
You can also use sapply using the number of columns in the matrix. Later, we use any to return True (if any) value from each column
Tr <- c(1,2,10)
sapply(seq(ncol(M)), function(x) any(f(M[,x], Tr)))
[1] TRUE FALSE TRUE
Convert your matrix to a data frame and then use the map2 function from the purrr package:
library(tidyr)
df <- as.data.frame(M)
unlist(map2(df, t, f))
Also it is a terrible idea to name a variable T (or F) as that can cause a ton of problems with logical terms.
mapply(f,as.data.frame(M),T)
as.data.frame is needed to convert M to the list of the matrix columns, and mapply applies f to the produced list and vector T in a pairwise fashion.

Returning head and tail means from list of vectors

I need to calculate the mean (or other summary functions) on the top x and bottom x portions on list of vectors of varying lengths.
Here is a list of 3 vectors of different lengths similar in format with what I am working with:
t <- list(a = exp(-4:3), b = exp(-2:12), c = exp(-5:3))
Ideally, I would like a single vector of numbers for each type of means (I manually ran mean(head(t$a),2)) and mean(tail(t$a),2)) for each vectors):
Ideal output yielding a nameless vector of means of the first two elements from each vector:
[1] 0.2516074 1.859141 0.09256118
Second vector of means for last two entries in each vector:
[1] 1.859141 15064.77 1.859141
Looking for a clever lapply-type construct to get a vector of numbers for each means without the attached names (in this case a,b,c). Thanks!
What about
n = 2
v = lapply(t, function(i) mean(head(i, n)))
The variable v is list. So to get a vector, just use unlist
v = unlist(v)
To extract the numbers use as.vector
as.vector(v)
For the tail, just use
lapply(t, function(i) mean(tail(i, n)))
Using sapply you can wrap this in a function:
sapply(dat,function(x,length=2)
c(mean(head(x,length)),mean(head(x,length))))
# a b c
# [1,] 0.03405135 0.2516074 0.01252679
# [2,] 0.03405135 0.2516074 0.01252679

Making a vector from list elements in R

I've got a list of lists of bootstrap statistics from a function that I wrote in R. The main list has the 1000 bootstrap iterations. Each element within the list is itself a list of three things, including fitted values for each of the four variables ("fvboot" -- a 501x4 matrix).
I want to make a vector of the values for each position on the grid of x values, from 1:501, and for each variable, from 1:4.
For example, for the ith point on the xgrid of the jth variable, I want to make a vector like the following:
vec = bootfits$fvboot[[1:1000]][i,j]
but when I do this, I get:
recursive indexing failed at level 2
googling around, i think I understand why R is doing this. but I'm not getting an answer for how I can get the ijth element of each fvboot matrix into a 1000x1 vector.
help would be much appreciated.
Use unlist() function in R. From example(unlist),
unlist(options())
unlist(options(), use.names = FALSE)
l.ex <- list(a = list(1:5, LETTERS[1:5]), b = "Z", c = NA)
unlist(l.ex, recursive = FALSE)
unlist(l.ex, recursive = TRUE)
l1 <- list(a = "a", b = 2, c = pi+2i)
unlist(l1) # a character vector
l2 <- list(a = "a", b = as.name("b"), c = pi+2i)
unlist(l2) # remains a list
ll <- list(as.name("sinc"), quote( a + b ), 1:10, letters, expression(1+x))
utils::str(ll)
for(x in ll)
stopifnot(identical(x, unlist(x)))
This would be easier if you give a minimal example object. In general, you can not index lists with vectors like [[1:1000]]. I would use the plyr functions. This should do it (although I haven't tested it):
require("plyr")
laply(bootfits$fvboot,function(l) l[i,j])
If you are not familiar with plyr: I always found Hadley Wickham's article 'The split-apply-combine strategy for data analysis' very useful.
You can extract one vector at a time using sapply, e.g. for i=1 and j=1:
i <- 1
j <- 1
vec <- sapply(bootfits, function(x){x$fvboot[i,j]})
sapply carries out the function (in this case an inline function we have written) to each element of the list bootfits, and simplifies the result if possible (i.e. converts it from a list to a vector).
To extract a whole set of values as a matrix (e.g. over all the i's) you can wrap this in another sapply, but this time over the i's for a specified j:
j <- 1
mymatrix <- sapply(1:501, function(i){
sapply(bootfits, function(x){x$fvboot[i,j]})
})
Warning: I haven't tested this code but I think it should work.

Resources