Reputation: 177
My data structure is as follows:
m
[[1]]
[[1]][[1]]
[1] "g" "g" "h" "k" "k" "k" "l"
[[2]]
[[2]][[1]]
[1] "g" "h" "k" "k" "k" "l" "g"
[[3]]
[[3]][[1]]
[1] "g" "h" "h" "h" "k" "l" "h"
I want to find positions of each unique characters simultaneously. Individually I can obtain positions of each character using the following code:
t<-list()
for (i in 1:length(m)){
for (j in m[[i]][[1]]){
if (j=="k"){
t[[i]]<-grep(j,m[[i]][[1]],fixed=TRUE)}}}
The result I obtain is as follows:
t
[[1]]
[1] 4 5 6
[[2]]
[1] 3 4 5
[[3]]
[1] 5
There are 4 unique characters in list m and I will get 4 lists with positions of unique characters using my code but I have to manually enter each character into the loop. I need a single code which will calculate positions for all the unique characters simultaneously.
Upvotes: 0
Views: 46
Reputation: 389095
We can use a double loop with lapply
where we check position using which
for each unique
value in m
lst <- lapply(unique(unlist(m)), function(x)
lapply(m, function(y) which(x == y[[1]])))
lst
#[[1]]
#[[1]][[1]]
#[1] 1 2
#[[1]][[2]]
#[1] 1 7
#[[1]][[3]]
#[1] 1
#[[2]]
#[[2]][[1]]
#[1] 3
#[[2]][[2]]
#[1] 2
#[[2]][[3]]
#[1] 2 3 4 7
......
To identify which values represent which character we can name the list
names(lst) <- unique(unlist(m))
lst
#$g
#$g[[1]]
#[1] 1 2
#$g[[2]]
#[1] 1 7
#$g[[3]]
#[1] 1
...
Upvotes: 0
Reputation: 132804
The vectors in your list seem all to be of equal length (if not this could be adjusted by making them equal length). I would first restructure the data:
m <- list(list(c("g", "g", "h", "k", "k", "k", "l")),
list(c("g", "h", "k", "k", "k", "l", "g")))
m <- do.call(rbind, lapply(m, "[[", 1))
# [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#[1,] "g" "g" "h" "k" "k" "k" "l"
#[2,] "g" "h" "k" "k" "k" "l" "g"
Then you can use outer
to make all comparisons at once:
res <- which(outer(m, unique(c(m)), "=="), arr.ind = TRUE)
res <- as.data.frame(res)
res$dim3 <- factor(res$dim3, labels = unique(c(m)))
names(res) <- c("list_element", "vector_element", "letter")
#check
res[res$letter == "k" & res$list_element == 1, "vector_element"]
[1] 4 5 6
This solution won't work well if your data is huge.
Upvotes: 1