R column names as list instead of vector [duplicate] - r

The vector is like this:
c(1,2,3)
#[1] 1 2 3
I need something like this:
list(1,2,3)
#[[1]]
#[1] 1
#
#[[2]]
#[1] 2
#
#[[3]]
#[1] 3
I tried this:
list(c(1,2,3))
#[[1]]
#[1] 1 2 3

Simple, just do this:
as.list(c(1,2,3))

An addition to the accepted answer: if you want to add a vector to other elements in a longer list, as.list() may not produce what you expect. For example: you want to add 2 text elements and a vector of five numeric elements (1:5), to make a list that is 7 elements long.
L<-list("a","b",as.list(1:5))
Oops: it returns a list with 3 elements, and the third element has a sub-list of 5 elements; not what we wanted! The solution is to join two separate lists:
L1<-list("a","b")
L2<-as.list(1:5)
L<-c(L1,L2) #7 elements, as expected

Related

How can I modify a vector inside a list?

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))

Create a list with True or False [duplicate]

The vector is like this:
c(1,2,3)
#[1] 1 2 3
I need something like this:
list(1,2,3)
#[[1]]
#[1] 1
#
#[[2]]
#[1] 2
#
#[[3]]
#[1] 3
I tried this:
list(c(1,2,3))
#[[1]]
#[1] 1 2 3
Simple, just do this:
as.list(c(1,2,3))
An addition to the accepted answer: if you want to add a vector to other elements in a longer list, as.list() may not produce what you expect. For example: you want to add 2 text elements and a vector of five numeric elements (1:5), to make a list that is 7 elements long.
L<-list("a","b",as.list(1:5))
Oops: it returns a list with 3 elements, and the third element has a sub-list of 5 elements; not what we wanted! The solution is to join two separate lists:
L1<-list("a","b")
L2<-as.list(1:5)
L<-c(L1,L2) #7 elements, as expected

concatenate vectors from two lists by names [duplicate]

This question already has answers here:
Merge Two Lists in R
(9 answers)
Merge contents within list of list by duplicate name
(1 answer)
Closed 3 years ago.
So I'm heavily simplifying my actual problem, but I am trying to find a way to append values inside vectors from one list, to values in vectors in another list, and do it by name ( assuming the two lists are not ordered).So this is the setup to the problem ( the numbers themselves are arbitrary here):
Data1 <- list( c(1),c(2),c(3))
names(Data1) <- c("A", "B","C")
Data2 <- list(c(11), c(12), c(13))
names(Data2) <- c("B","A","C")
Now what Im trying to do, is find a way to get a third list - say Data3, so that calling Data3[["A"]] will give me the same result as calling c(1,12):
[1] 1 12
so >Data3 should give:
[1] 1 12
[2] 2 11
[3] 3 13
Essentially im looking to append many values from one list of vectors, to another list of vectors, and do it by names rather than order, if that makes sense. (I did think about trying some loops, but I feel like there should be another way that is simpler)
nm = names(Data1)
setNames(lapply(nm, function(x){
c(Data1[[x]], Data2[[x]])
}), nm)
#$A
#[1] 1 12
#$B
#[1] 2 11
#$C
#[1] 3 13
list(do.call("cbind", list(Data1, Data2)))
[,1] [,2]
A 1 11
B 2 12
C 3 13
If you don't mind your output to be a dataframe:
Data3 <- rbind(data.frame(Data1), data.frame(Data2))
Then Data3[["A"]] will give you:
[1] 1 12
We can use Map and arrange the elements of Data2 in the same order as Data1 (or vice versa) using names and then concatenate them.
Map(c, Data1, Data2[names(Data1)])
#$A
#[1] 1 12
#$B
#[1] 2 11
#$C
#[1] 3 13

finding the index of list elements which are greater than 0

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.

Extract a column from a data.table as a vector, by position

How do I extract a column from a data.table as a vector by its position? Below are some code snippets I have tried:
DT<-data.table(x=c(1,2),y=c(3,4),z=c(5,6))
DT
# x y z
#1: 1 3 5
#2: 2 4 6
I want to get this output using column position
DT$y
#[1] 3 4
is.vector(DT$y)
#[1] TRUE
Other way to get this output using column position
DT[,y]
#[1] 3 4
is.vector(DT[,y])
#[1] TRUE
This doesn't give a vector
DT[,2,with=FALSE]
# y
#1: 3
#2: 4
is.vector(DT[,2,with=FALSE])
#[1] FALSE
Those two doesn't work:
DT$noquote(names(DT)[2]) # Doesn't work
#Error: attempt to apply non-function
DT[,noquote(names(DT)[2])] # Doesn't work
#[1] y
And this doesn't give a vector:
DT[,noquote(names(DT)[2]),with=FALSE] # Not a vector
# y
#1: 3
#2: 4
is.vector(DT[,noquote(names(DT)[2]),with=FALSE])
#[1] FALSE
A data.table inherits from class data.frame. Therefore it is a list (of column vectors) internally and can be treated as such.
is.list(DT)
#[1] TRUE
Fortunately, list subsetting, i.e. [[, is very fast and, in contrast to [, package data.table doesn't define a method for it. Thus, you can simply use [[ to extract by an index:
DT[[2]]
#[1] 3 4
DT[,get(names(DT)[colNb])]
where colNb can be an integer (the desired column number) or a variable containing the column number.

Resources