Reputation: 137
I have a large list of lists of matrices. The format can be seen here:
These are 50 matrices but divided into sublists and ordered. What I need is one list of 50 matrices in random order while keeping the names which are characters 0-10. Example:
0: [1:28, 1:28] 0 0 0 ...
5: [1:28, 1:28] 0 0 0 ...
3: [1:28, 1:28] 0 0 0 ...
0: [1:28, 1:28] 0 0 0 ...
8: [1:28, 1:28] 0 0 0 ...
8: [1:28, 1:28] 0 0 0 ...
Upvotes: 0
Views: 107
Reputation: 13581
You can try this
Data
data <- lapply(1:10, function(i) lapply(1:5, function(j) matrix(1:(28*28), nrow=28)))
names(data) <- 1:10
str(data)
# List of 10
# $ 1 :List of 5
# ..$ : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 2 :List of 5
# ..$ : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# ..$ : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# etc
purrr::flatten
your list
EDIT If each list has a different length, you can use names(result) <-
rep(1:length(data), times=(lengths(data)))
instead
library(purrr)
result <- flatten(data)
names(result) <- rep(1:length(data), times=(lengths(data)))
str(result)
# List of 50
# $ 1 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 1 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 1 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 1 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 1 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 2 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 2 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 2 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# etc
Shuffle
set.seed(1)
ans <- result[sample(1:50)]
str(ans)
# List of 50
# $ 3 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 4 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 6 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 9 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 2 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 9 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 9 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# $ 6 : int [1:28, 1:28] 1 2 3 4 5 6 7 8 9 10 ...
# etc
Upvotes: 1
Reputation: 76460
Without a dataset example I don't know if this runs but here it goes.
set.seed(3694)
inx <- sample(names(trainData), 50, TRUE)
tmp <- lapply(inx, function(i){
lst <- trainData[[i]]
mat <- lst[[sample(seq_along(lst), 1)]]
list(i, mat)
})
result <- lapply(tmp, `[[`, 2)
names(result) <- sapply(tmp, `[[`, 1)
rm(tmp)
EDIT.
Tested with the data by CPak, a bug in the names of the result was corrected. It now seems to do what the OP is asking for.
Upvotes: 2
Reputation: 2254
What about using sample(...)? Running it second time gives you new permutation:
> a = list('0'=list(2,3),'1'=2,'2'=3)
> a
$`0`
$`0`[[1]]
[1] 2
$`0`[[2]]
[1] 3
$`1`
[1] 2
$`2`
[1] 3
> sample(a,length(a))
$`1`
[1] 2
$`2`
[1] 3
$`0`
$`0`[[1]]
[1] 2
$`0`[[2]]
[1] 3
> sample(a,length(a))
$`2`
[1] 3
$`1`
[1] 2
$`0`
$`0`[[1]]
[1] 2
$`0`[[2]]
[1] 3
Upvotes: 1