Before going straight to Rcpp I would encourage you to think about how we could do this in base R. List, subsetting, and indexing are the bread and butter of base R and can be quite efficient.
Below, we have a solution that attacks your problem. You will note, it could probably be more efficient, but for now, this is very straightforward approach and is easy to understand. We will test the efficiency later and address any concerns then.
A_prime <- function(A) {
## Generate index vector for all of A
ind <- seq_len(sum(unlist(lapply(A, lengths))))
## Generate the ending index of each vector
endInd <- cumsum(lengths(unlist(A, recursive = F)))
## Use the endInd to create the corresponding start index
startInd <- c(1L, endInd[-length(endInd)] + 1L)
## Create a simple list with the appropriate index vector
A_ind <- mapply(function(s, e) ind[s:e], startInd, endInd, SIMPLIFY = FALSE)
## Again, using the structure of A, we begin creating starting
## and ending indices to replicate the structure of A
A_end <- cumsum(lengths(A))
A_strt <- c(1L, A_end[-length(A_end)] + 1L)
## Create the desired result
lapply(seq_along(A), function(x) A_ind[A_strt[x]:A_end[x]])
}
Let's test it on a similar problem that the OP has presented:
set.seed(35)
a <- sort(sample(10000, 60))
L1 <- lapply(seq.int(1, 60, 3), function(x) {
a[x:(x + 2)]
})
A <- list(L1[1:10], L1[11:20])
str(A)
List of 2
$ :List of 10
..$ : int [1:3] 4 203 205
..$ : int [1:3] 710 1281 1515
..$ : int [1:3] 1605 1784 1846
..$ : int [1:3] 1904 1993 2425
..$ : int [1:3] 2468 2499 2630
..$ : int [1:3] 2910 2920 3210
..$ : int [1:3] 3360 3464 3469
..$ : int [1:3] 3689 3811 4002
..$ : int [1:3] 4053 4304 4358
..$ : int [1:3] 4433 5290 5862
$ :List of 10
..$ : int [1:3] 6017 6021 6155
..$ : int [1:3] 6250 6370 6414
..$ : int [1:3] 6447 6530 6656
..$ : int [1:3] 6706 6820 6977
..$ : int [1:3] 6986 7148 7338
..$ : int [1:3] 7515 7522 7666
..$ : int [1:3] 7755 7889 7891
..$ : int [1:3] 8071 8143 8487
..$ : int [1:3] 8625 8731 8945
..$ : int [1:3] 8957 9149 9770
And here is the output:
str(A_prime(A))
List of 2
$ :List of 10
..$ : int [1:3] 1 2 3
..$ : int [1:3] 4 5 6
..$ : int [1:3] 7 8 9
..$ : int [1:3] 10 11 12
..$ : int [1:3] 13 14 15
..$ : int [1:3] 16 17 18
..$ : int [1:3] 19 20 21
..$ : int [1:3] 22 23 24
..$ : int [1:3] 25 26 27
..$ : int [1:3] 28 29 30
$ :List of 10
..$ : int [1:3] 31 32 33
..$ : int [1:3] 34 35 36
..$ : int [1:3] 37 38 39
..$ : int [1:3] 40 41 42
..$ : int [1:3] 43 44 45
..$ : int [1:3] 46 47 48
..$ : int [1:3] 49 50 51
..$ : int [1:3] 52 53 54
..$ : int [1:3] 55 56 57
..$ : int [1:3] 58 59 60
That looks pretty good! A benefit of the function A_prime is that the nested list need not be uniform. Let's test this on a very large list with over 10Mb of data:
set.seed(123)
big_ind <- sort(sample(1e8, 1e6))
## generate random chunks
endIndBig <- sort(sample(1e6, 1e5))
startIndBig <- c(1L, endIndBig)
endIndBig <- c(endIndBig, 1e6)
A_big_init <- mapply(function(s, e) big_ind[s:e], startIndBig, endIndBig, SIMPLIFY = FALSE)
## generate random chunks for nested lists
A_big_ends <- sort(sample(length(A_big_init), 1e3))
A_big_strts <- c(1L, A_big_ends)
A_big_ends <- c(A_big_ends, length(A_big_init))
A_big <- lapply(seq_along(A_big_ends), function(x) A_big_init[A_big_strts[x]:A_big_ends[x]])
Here is some summary information on A_big. As you can see the length of each sub list is not uniform:
print(object.size(A_big), units = "Mb")
# 10.7 Mb
length(A_big)
# [1] 1001
head(lengths(A_big))
# [1] 159 175 59 69 175 38
tail(lengths(A_big))
# [1] 88 4 225 91 74 59
A_big[[1]][[1]]
# [1] 3 72 722 836 929 1014 1091 1127
A_big[[1]][[159]]
# [1] 170285 170370 170482 170763 170793 170913 170965 171066 171240 171397 171464 171572 171590 171722
# [15] 171898 171903 172196 172284 172298 172590 172696 172698
A_big[[1000]][[2]]
# [1] 99856337 99856415
A_big[[1000]][[74]]
# [1] 99938669 99938699 99938743 99939158 99939664 99939803
Now, for the moment of truth...
system.time(A_prime(A_big))
user system elapsed
0.201 0.003 0.203
A_big_prime <- A_prime(A_big)
A_big_prime[[1]][[1]]
# [1] 1 2 3 4 5 6 7 8
A_big_prime[[1]][[159]]
# [1] 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898
# [21] 1899 1900
A_big_prime[[1000]][[2]]
# [1] 1109671 1109672
A_big_prime[[1000]][[74]]
# [1] 1110583 1110584 1110585 1110586 1110587 1110588
That's not bad!!! As we can see, the mapping was performed correctly and quickly all with base R.