Create a list with True or False [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

R column names as list instead of vector [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

how to acces list elements based on condition in r [duplicate]

This question already has answers here:
Remove empty elements from list with character(0)
(5 answers)
Closed 3 years ago.
This sseems me very simple, however I can not get good graps on it. Lets say I have list like this:
my_list=list(integer(0),c(4,3,3),integer(0),integer(0),c(5,2,5),integer(0))
I used integer(0) to make it similar to my original data but any condition here is applicable. Now i want to extract from my list only those elements that are NOT integer(0) making new 2-element list like this:
list_I_try_to_make=list(c(4,3,3),c(5,2,5))
I know how to do this for data frame but I am not sure how to correctly adress each element of list. I tried lapply with condition for each element but this simply returns me new list with same length where each element is an answer (if length>0 it only returns TRUE/FALSE)
You can use the purrr package which is very convenient when working with lists.
library(purrr)
keep(my_list, function(x) length(x) > 0)
You can use lengths
my_list[lengths(my_list) > 0]
[[1]]
[1] 4 3 3
[[2]]
[1] 5 2 5
This is one solution :
my_list[ !unlist(lapply(my_list,identical,integer(0))) ]
Try with this:
my_filter=unlist(lapply(my_list,length))>0
my_list[my_filter]
[[1]]
[1] 4 3 3
[[2]]
[1] 5 2 5
You can use Filter:
my_list <- list(integer(0),c(4,3,3),integer(0),integer(0),c(5,2,5),integer(0))
Filter(function(x) length(x)>0, my_list)
# [[1]]
# [1] 4 3 3
#
# [[2]]
# [1] 5 2 5

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