Access nested structure - r

Are there some nice designs to call data in a nested structure e.g.
a<-list(list(LETTERS[1:3],LETTERS[1:3]),list(LETTERS[4:6]))
lapply(a,function(x) lapply(x, function(x) x))
but unlist is not a option.

Not as good as #SimonO101's answer but just for providing as an alternative you can do it using do.call
> do.call(c,do.call(c, a))
[1] "A" "B" "C" "A" "B" "C" "D" "E" "F"
Also using Reduce
> do.call(c, Reduce(c, a))
[1] "A" "B" "C" "A" "B" "C" "D" "E" "F"

Recursive lapply... a.k.a rapply?
rapply( a , c )
[1] "A" "B" "C" "A" "B" "C" "D" "E" "F"

Related

data.table filter doesn't work in with()?

I am filetering a data.table based on another data.table, and it gives a very odd result.
please advise,
library(data.table)
library(magrittr)
set.seed(100)
xA = data.table(A = letters[1:4], B = sample(1:1000))
xB = data.table(A = letters[1:4], B = sample(1:100))
with(xA[30], {
sprintf(" xA A = %s B = %s", A, B) %>% print
xB[A == A]$A %>% print
print("")
xB[A == "b"]$A %>% print
})
#[1] " xA A = b B = 322"
# [1] "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" #"d" "a" "b" "c" "d" "a" "b" "c" "d" "a" "b"
# [35] "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" "a" #"b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d"
# [69] "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" "d" "a" "b" "c" #"d" "a" "b" "c" "d" "a" "b" "c" "d"
#[1] " xA A = b B = 322"
# [1] "b" "b" "b" "b" "b" "b" "b" "b" "b" "b" "b" "b" "b" "b" "b" "b" "b" "b" #"b" "b" "b" "b" "b" "b" "b"
With the toy code, it shall give a result of all b as the second result, but it gave everything as first printout. How come? Thanks for advice.
The problem is when you just look at the statement
xB[A == A]
How do you know which is a column name and which is a variable name? In this case, data.table just assumes you want all rows where column A is equal to itself (which is all of them. Try using a differnt variable name
with(xA[30], {
sprintf(" xA A = %s B = %s", A, B) %>% print
a <- A
xB[A == a]$A
})

Smartest way for making a sequence of characters in R

I am going to make the below sequence in R:
A A B B B A A B B B
I have used the below code:
rep(c("A","A","B","B","B"),2)
I got the correct answer as follows:
[1] "A" "A" "B" "B" "B" "A" "A" "B" "B" "B"
But I don't like my code. I would like to see the smartest way for making the above sequence. I don't know if it is possible to make the above sequence using LETTERS[1:2].
Thank you in advance
You can do it without using rep at all:
LETTERS[(0:9 %% 5 > 1) + 1]
[1] "A" "A" "B" "B" "B" "A" "A" "B" "B" "B"
Here you just replace 9 with however long you want the sequence to be.
You can use rep twice :
rep(rep(LETTERS[1:2], c(2, 3)), 2)
#[1] "A" "A" "B" "B" "B" "A" "A" "B" "B" "B"
A Reduce() version of #RonakShah's answer.
Reduce(rep, list(c(2, 3), 2), LETTERS[1:2])
# [1] "A" "A" "B" "B" "B" "A" "A" "B" "B" "B"
Another variant using rep and LETTERS:
LETTERS[rep(rep(1:2, 2:3), 2)]
# [1] "A" "A" "B" "B" "B" "A" "A" "B" "B" "B"
An option with replicate
unlist(replicate(2, Map(rep, LETTERS[1:2], c(2, 3))))
#[1] "A" "A" "B" "B" "B" "A" "A" "B" "B" "B"

List of string to list of vectors of characters

After defining
> Seq.genes <- as.list(c("ATGCCCAAATTTGATTT","AGAGTTCCCACCAACG"))
I have a list of strings :
> Seq.genes[1:2]
[[1]]
[1] "ATGCCCAAATTTGATTT"
[[2]]
[1] "AGAGTTCCCACCAACG"
I would like to convert it in a list of vectors :
>Seq.genes[1:2]
[[1]]
[1]"A" "T" "G" "C" "C" "C" "A" "A" "A" "T" "T" "T" "G" "A" "T" "T" "T"
[[2]]
[1] "A" "G" "A" "G" "T" "T" "C" "C" "C" "A" "C" "C" "A" "A" "C" "G"
I tried something like :
for (i in length(Seq.genes)){
x <- Seq.genes[i]
Seq.genes[i] <- substring(x, seq(1,nchar(x),2), seq(1,nchar(x),2))
}
It may be better to have the strings in a vector rather than in a list. So, we could unlist, then do an strsplit
strsplit(unlist(Seq.genes), "")
sapply(Seq.genes, strsplit, split = '')
or
lapply(Seq.genes, strsplit, split = '')

How can I split a string and add them to vector?

I'd like to split a character vector so that additional members are added to the length of the vector.
> va <- c("a", "b", "c;d;e")
[1] "a" "b" "c;d;e"
> vb <- strsplit(va, ";")
[[1]]
[1] "a"
[[2]]
[1] "b"
[[3]]
[1] "c" "d" "e"
Can can I get vb vector in the same format as va vector so that I get 1-dimensional, 5 member vector in vb as such?
[1] "a" "b" "c" "d" "e"
Appreciate the help.
One possibility:
unlist(vb)
# [1] "a" "b" "c" "d" "e"
Or
scan(text=va, sep=";",what="")
#Read 5 items
# [1] "a" "b" "c" "d" "e"

R: repeat elements of a list based on another list

I have searched for this but in vain.
the problem is I have two lists, first with the elements to be repeated
for example
my.list<-list(c('a','b','c','d'), c('g','h'))
and the second list is the number of times each element is to be repeated
repeat.list<-list(c(5,7,6,1), c(2,3))
I would like to create a new list in which each element in my.list is repeated based in repeat.list
i.e.
result:
[[1]]
[1] "a" "a" "a" "a" "a" "b" "b" "b" "b" "b" "b" "b" "c" "c" "c" "c" "c" "c" "d"
[[2]]
[1] "g" "g" "h" "h" "h"
Thank you in advance for your help
Use mapply:
mapply(rep, my.list, repeat.list)
[[1]]
[1] "a" "a" "a" "a" "a" "b" "b" "b" "b" "b" "b" "b" "c" "c" "c" "c" "c" "c" "d"
[[2]]
[1] "g" "g" "h" "h" "h"
lapply also does the trick, but is more verbose:
lapply(seq_along(my.list), function(i)rep(my.list[[i]], repeat.list[[i]]))
[[1]]
[1] "a" "a" "a" "a" "a" "b" "b" "b" "b" "b" "b" "b" "c" "c" "c" "c" "c" "c" "d"
[[2]]
[1] "g" "g" "h" "h" "h"

Resources