I am using lapply to select elements from vectors in a list, but not all vectors in the list include the same number of elements. I typically use:
lapply(some.list,"[[",n)
were n is the index of the element in the vectors I am trying to parse out. However, this time my list looks more like this:
some.vect <- c("aaa_elem1","aa_elem2","elem3","bb_elem4","ccc_elem5","abc_elem6")
some.list <- strsplit(some.vect,"_")
When I use my normal lapply method:
lapply(some.list,"[[",2)
I get the following error: Error in FUN(X[[3L]], ...) : subscript out of bounds as expected, because not all vectors in the list have two elements. What I would like is a way to declare the index in lapply as the length of the vector.
I also tried defining a vector of the list vector lengths, and assigning it to index:
vect.length <- unlist(lapply(some.list,length))
lapply(some.list,"[[",vect.length)
(Error in FUN(X[[1L]], ...) : attempt to select more than one element)
and not assigning an index at all:
lapply(some.list,"[[")
(Error in FUN(X[[1L]], ...) : no index specified)
Is there a way to select all of the last elements of vectors in a list?
Use tail...
lapply(some.list, tail , 1 )
Related
Using the default "iris" DataFrame in R, how come when creating a new column "NewCol"
iris[,'NewCol'] = as.POSIXlt(Sys.Date()) # throws Warning
BUT
iris$NewCol = as.POSIXlt(Sys.Date()) # is correct
This issue doesn't exist when assigning Primitive types like chr, int, float, ....
First, notice as #sindri_baldur pointed, as.POSIXlt returns a list.
From R help ($<-.data.frame):
There is no data.frame method for $, so x$name uses the default method which treats x as a list (with partial matching of column names if the match is unique, see Extract). The replacement method (for $) checks value for the correct number of rows, and replicates it if necessary.
So, if You try iris[, "NewCol"] <- as.POSIClt(Sys.Date()) You get warning that You're trying assign a list object to a vector. So only the first element of the list is used.
Again, from R help:
"For [ the replacement value can be a list: each element of the list is used to replace (part of) one column, recycling the list as necessary".
And in Your case, only one column is specified meaning only the first element of the as.POSIXlt's result (list) will be used. And You are warned of that.
Using $ syntax the iris data.frame is treated as a list and then the result of as.POSIXlt - a list again - is appended to it. Finally, the result is data.frame, but take a look at the type of the NewCol - it's a list.
iris[, "NewCol"] <- as.POSIXlt(Sys.Date()) # warning
iris$NewCol2 <- as.POSIXlt(Sys.Date())
typeof(iris$NewCol) # double
typeof(iris$NewCol2) # list
Suggestion: maybe You wanted to use as.POSIXct()?
I am currently building a reccursive loop in R, where I have to keep track of how deep I am in a nested list. I, however, have run into problems when counting in nested lists.
Here is the problem illustrated:
I have a list
myList <- list()
I test the value of a random index in the list
myList[["test1"]]
NULL
I can sum this value and get zero
sum(myList[["test1"]])
0
Now I assign a value to this index
myList[["test1"]] <- sum(myList[["test1"]]) + 1
Next I want to do the same just deeper into the list
myList[["test1"]][["test2"]]
Error in myList[["test1"]][["test2"]] : subscript out of bounds
Why is this happening?
When you set the value of myList[["test1"]] with...
myList[["test1"]] <- sum(myList[["test1"]]) + 1
myList[["test1"]] becomes a 1 element numeric vector, not a list
If you want to make test1 a list, with one of its elements being another (sub)list called test2, you can do this...
myList <- list()
myList[["test1"]] <- list(sum(myList[["test1"]]) + 1)
myList[["test1"]]["test2"] <- list(sum(myList[["test1"]][[1]]) + 1)
myList
myList$test1
myList$test1$test2
I'm not sure what you're trying to do, but this is a simpler version of what you did:
> x<-1
> x[["test2"]]
Error in x[["test2"]] : subscript out of bounds
Here x is a numeric vector. It can still be subscripted using [[ but there is no element named test2 in x, so you get an "out of bounds" error when you try to access that element.
Even a vector with more than one element would give this error:
> c(1,2)[["test2"]]
Error in c(1, 2)[["test2"]] : subscript out of bounds
However, if we name one of them test2 then the subscripting returns something:
> c(1,2,test2=3)[["test2"]]
[1] 3
I've got a list of dataframes and am trying to change the first colname using the lapply method
frames<-lapply(frames,function(x){ colnames(frames[[x]])[1]<-"date"})
is returning the error
Error in `*tmp*`[[x]] : invalid subscript type 'list'
I am not sure why it would produce this error as my understanding is that this should apply
colname[1]<-"date"
to every data frame in the list
If anyone can tell me the root of this error I would be very grateful!
You do not need to reference the frames list inside of lapply. Your function treats x as an element in the list, frames. Try this:
frames <- lapply(frames, function(x) { colnames(x)[1] <- "date"; return(x) })
I have very big list, every component of that list. I need to get the value of called of variable called cv . it work with other lists, but in some list I face with error:
Error in x$cvm : $ operator is invalid for atomic vectors
How can I filter out this vectors from my list before running my code?
Here is what my code do:
MES<-lapply(mylist, function(x) x$cvm[x$lambda == x$lambda.min])
it works well, but in some list, it's produce already mentioned error.
$ are valid e.g. for lists (and environments, but probably it's not your case). To filter out all elements which are not lists, call:
mylist2 <- mylist[sapply(mylist, is.list)]
I am quite new to R and I have found one vector operation frustrating:
I just want to know an index of current element of the list while using sapply, let's say: to print an index, but all my trials do not work, e.g.:
> test <- sapply(my.list.of.matrices,
function(x) print(which(my.list.of.matrices == x)))
Error in which(my.list.of.matrices == x) :
(list) object cannot be coerced to type 'logical'
In addition: Warning message:
In my.list.of.matrices == x :
longer object length is not a multiple of shorter object length
That's not possible unless you pass an index vector. sapply and lapply just pass the elements. And in that case it becomes a disguised for-loop.