I have a list containing three vectors, say:
test <- list(c(1,2,3,4),c(5,6,7),c(8,9,10))
I'd like to add elements to a given vector in the list. Let's say I'd like to add 11 to the last one (offset 3), so I'd have c(8,9,10,11) as the last element of the "test" list.
I tried:
test[3] <- c(test[3], 11)
test[[3]] <- c(test[1], 11)
test[3[length(test[3])] <- 11
append(test[3], 11)
And apparently nothing of the above works as I expect it to.
How can I do this?
Extract one item with [[
The double square brackets are used to extract one element from potentially many. For vectors yield vectors with a single value; data frames give a column vector; for list, one element text from here
after this use c() to concatenate:
test[[3]] <- c(test[[3]],11)
test[[3]]
[[1]]
[1] 1 2 3 4
[[2]]
[1] 5 6 7
[[3]]
[1] 8 9 10 11
A purrr option (corrected by Ritchie's comment):
test |> purrr::map_at(3, ~ c(.x, 11))
Related
Suppose I have a long vector with characters which is more or less like this:
vec <- c("32, 25", "5", "15, 24")
I want to apply a function which give me the number of strings for any element separated by a comma and returns me a vector with any individual length. Using lapply and my toy vector, this is my approach:
lapply(vec, function(x) {
a <- strsplit(x, ",")
y <- length(a[[1:length(a)]])
unlist(y[1:length(y)])
})
[[1]]
[1] 2
[[2]]
[1] 1
[[3]]
[1] 2
This almost gives me what I want since first element has 2 strings, second element 1 string and third element 2 strings. The problem is I can't achieve that my function returns me a vector of the form c(2,1,2). I'm using this function to create a new variable on some data.frame which I'm working with.
Any idea will be much appreciated.
You could do:
stringr::str_count(vec, ",") + 1
#> [1] 2 1 2
Or, in base R:
nchar(gsub("[^,]", "", vec)) + 1
#> [1] 2 1 2
This question already has answers here:
The difference between bracket [ ] and double bracket [[ ]] for accessing the elements of a list or dataframe
(11 answers)
Closed 2 years ago.
how to access elements from a vector that resides in a list
not clear why it works like in de code example
l[2] is a vector
l[2][1] is expected to refer to the 1st element of the vector
l <- list( 0, c(1,7,12))
l[2][1] # does not work, gives.....[1] 1 7 12
l[2][[1]][1] # does work as desired, gives [1] 1, but don no why
l[2][[1]][2] # gives [1] 7, as desired
Your can access it using l[[2]][1]
you can look at the output of l to see how items are organised. This can give you a clue as to how to call them
> l
[[1]]
[1] 0
[[2]]
[1] 1 7 12
In general, when you use the single bracket notation, R returns an element of the same class as the original object.
l is a list, so when you access an element of the list, e.g. l[2], R returns the element you asked for but wrapped in a list.
> l[2]
[[1]]
[1] 1 7 12
> class(l[2])
[1] "list"
If you want to "peel away" this layer, you use the double bracket syntax. R will then return the actual object at that index.
> l[[2]]
[1] 1 7 12
> class(l[[2]])
[1] "numeric"
Now you can access the elements of the vector.
> l[[2]][1]
[1] 1
> l[[2]][2]
[1] 7
If we use pluck, it is more easier
library(purrr)
pluck(l, 2, 1)
#[1] 1
I have a list, "my_list", below:
$`2015-03-01 00:18:50`
integer(0)
$`2015-03-01 11:19:59`
[1] 4 6
$`2015-03-01 12:18:29`
[1] 12 13
$`2015-03-01 13:19:09`
[1] 1
$`2015-03-01 17:18:44`
integer(0)
$`2015-03-01 22:18:49`
integer(0)
I want to get the element index (not the subelement index) of the values greater than 0 (or where a list subelement is NOT empty). The output expected is a list that looks like:
2,2,3,3,4
I have gotten close with:
indices<-which(lapply(my_list,length)>0)
This piece of code however, only gives me the following and doesn't account for there being more than one subelement within a list element:
2,3,4
Does anyone know how to achieve what I am looking for?
We can use lapply along with a seq_along trick to bring in the indices of each element of the list. Then, for each list element, generate a vector of matching indices. Finally, unlist the entire list to obtain a single vector of matches.
x <- list(a=integer(0),b=c(4,6),c=c(12,13),d=c(1),e=integer(0),f=integer(0))
result <- lapply(seq_along(x), function(i) { rep(i, sum(x[[i]] > 0)) })
unlist(result)
[1] 2 2 3 3 4
Demo
You can try this, I hope this is what you have expected, Using lengths to calculate length of items in the list, then iterating every items of that list in rep command to get the final outcome:
lyst <- list(l1=integer(0), l2= c(1,2), l3=c(3,4), l4=character(0), l5=c(5,6,6))
lyst1 <- lengths(lyst)
unlist(lapply(1:length(lyst1), function(x)rep(x, lyst1[[x]])))
Output:
#> unlist(lapply(1:length(lyst1), function(x)rep(x, lyst1[[x]])))
#[1] 2 2 3 3 5 5 5
Repeat each numeric index by the respective length:
rep(seq_along(x), lengths(x))
#[1] 2 2 3 3 4
Using #Tim's x data.
sorry for the elementary question but I need to partition a list of numbers at an offset of 1.
e.g.,
i have a list like:
c(194187, 193668, 192892, 192802 ..)
and need a list of lists like:
c(c(194187, 193668), c(193668, 192892), c(192892, 192802)...)
where the last element of list n is the first of list n+1. there must be a way to do this with
split()
but I can't figure it out
in mathematica, the command i need is Partition[list,2,1]
You can try like this, using zoo library
library(zoo)
x <- 1:10 # Vector of 10 numbers
m <- rollapply(data = x, 2, by=1, c) # Creates a Matrix of rows = n-1, each row as a List
l <- split(m, row(m)) #splitting the matrix into individual list
Output:
> l
$`1`
[1] 1 2
$`2`
[1] 2 3
$`3`
[1] 3 4
Here is an option using base R to create a vector of elements
v1 <- rbind(x[-length(x)], x[-1])
c(v1)
#[1] 194187 193668 193668 192892 192892 192802
If we need a list
split(v1, col(v1))
data
x <- c(194187, 193668, 192892, 192802);
I have some json data [{a:10, b:123,c:4.5},{a:2,b:5,c:33}] and so on that I read into R via json_data <- fromJSON(paste(json_file, collapse="")) (json_file is the input url). So far so fine.
Now I would like to create vectors from this input which fromJSON has converted into a List of vectors where the vectors have components a,b,c.
Is there a better way than looping over the input list and doing this manually by concatenating the individual vector components on the new target vector(s)?
If you have a list like this:
l <- list(c(a=10, b=123, c=4.5),c(a=2,b=5,c=33))
You could just do something like the following:
df <- data.frame(do.call(rbind, l))
# a b c
# 1 10 123 4.5
# 2 2 5 33.0
as.list(df)
# $a
# [1] 10 2
# $b
# [1] 123 5
# $c
# [1] 4.5 33.0
(The do.call(rbind, X) construct is handy, allowing you to rbind together the elements of a list of arbitrary length. You can then slice and dice the resulting matrix as you see fit --- I just converted it to a data.frame and then to a list to show a couple of possibilities.)