R shuffle lists with repeated elements - r

I have multiple lists in R, each list has unique elements but some elements are in multiple lists. I want to shuffle the lists but also have each list have only unique elements. Here is something but this doesn't end up with unique lists at the end
x<-list()
x[[1]]<-c(1,2,3,4,5)
x[[2]]<-c(1,2,6,7,8)
u<-unlist(x)
x2<-relist(u[sample(length(u))],skeleton=x)
> x
[[1]]
[1] 1 2 3 4 5
[[2]]
[1] 1 2 6 7 8
> x2
[[1]]
[1] 4 8 3 5 6
[[2]]
[1] 2 1 2 1 7
Trying to figure out extra step to make sure each list has five unique numbers.

In your example the vectors already contain only unique values, so I think the solution can be as simple as:
x <- list(c(1,2,3,4,5), c(1,2,6,7,8))
lapply(x, sample)
# [[1]]
# [1] 3 2 5 1 4
#
# [[2]]
# [1] 1 6 7 2 8

Related

Find sequences in vector that do not match a pattern

I want to find sequence of elements in vector that do not match a pattern.
For example:
pattern <- c(1,2,3,4)
test <- c(5,4,3,6,1,2,3,4,5,3,3,2,1,2,3,4,6,3,7,5,1,2,3,6)
I want to find whole sequence in "test" that do not match "pattern" or indexes where this situation occurs.
So I want to get a result similar to this:
> want
[[1]]
[1] 5 4 3 6
[[2]]
[1] 5 3 3 2
[[3]]
[1] 6 3 7 5 1 2 3 6
or something like this:
> indexes
[1] 1 9 17
Do you have an idea how to do this?
One option is
lapply(scan(text=gsub(paste(pattern,collapse=""), ",",
paste(test, collapse="")), what="", sep=",", quiet = TRUE),
function(x) as.numeric(unlist(strsplit(x, ""))))
#[[1]]
#[1] 5 4 3 6
#[[2]]
#[1] 5 3 3 2
#[[3]]
#[1] 6 3 7 5 1 2 3 6

Recursive looping in r

I am new in R but I want to loop through elements of a given list recursively, to be presice I have alist of vectors where the first vector is given by (1,2,3,4), then I now want to loop through this vector and append the second vector obtained to the original list, again loop thorugh second vector in the list and get the third vector which is also appended on the original list and so on. I have this code to start with`
occlist <- list()
occ_cell <- c(1,2,3,4)
for(i in occ_cell){
occ_cell <- seq(i,4*i, by = 1)
occlist[[i]] <- occ_cell
}
`
gives the following list
#[[1]]
#[1] 1 2 3 4
#[[2]]
#[1] 2 3 4 5 6 7 8
#[[3]]
# [1] 3 4 5 6 7 8 9 10 11 12
#[[4]]
# [1] 4 5 6 7 8 9 10 11 12 13 14 15 16
I think to be more clear, lets have the following figure
recOcc <- function(i) {
if (i == 0) return ( NULL )
append( recOcc(i-1), list(seq(i, 4*i)) )
}
And, call with (to reproduce your output)
recOcc(4)
# [[1]]
# [1] 1 2 3 4
#
# [[2]]
# [1] 2 3 4 5 6 7 8
#
# [[3]]
# [1] 3 4 5 6 7 8 9 10 11 12
#
# [[4]]
# [1] 4 5 6 7 8 9 10 11 12 13 14 15 16
You can also use Recall to name your recursive function in the recursive call, which allows for the function name to change.
Edit
For the tree structure, you could try this
## i is the number to start the sequence
## depth determines how deep to recurse
recOcc2 <- function(i, depth=3, cur.depth=0) {
if (depth==cur.depth) return(seq(i, 4*i))
acc <- as.list(seq(i, 4*i))
for (ii in seq_along(acc))
acc[[ii]] <- recOcc2(acc[[ii]], depth, cur.depth+1)
acc
}
## To recreate the simple list
res <- recOcc2(1, depth=1)
## For nested lists
res <- recOcc2(1, depth=2)

Read in R a file with different line lengths into a List

I would like to read a file into a list of arrays with each line representing a list element. Each line has a different number of elements and different The first value in the line would be the list key and the remaining data would be the members of the array.
e.g. file example
1 100,50,2,5,78
2 5,4,2,1
3 1
4 7,2,9,0,23,5,6,7,8,2,3,4
5 1,2,3,4,5,6,7,8,9,0
6 1,8
I think this should work well
dd<-scan("example.txt", list("character", "character"))
Map(function(a,b)b, dd[[1]], strsplit(dd[[2]],","))
Here use use scan to read the first column as one vector and the second as another. Then we strsplit the second on commas and use one of the side-effects of Map to pull the names from the first column and use them as labels of the vectors from the second column. If you wanted the vector values to be numeric you could do
Map(function(a,b) as.numeric(b), dd[[1]], strsplit(dd[[2]],","))
# $`1`
# [1] 100 50 2 5 78
#
# $`2`
# [1] 5 4 2 1
#
# $`3`
# [1] 1
#
# $`4`
# [1] 7 2 9 0 23 5 6 7 8 2 3 4
#
# $`5`
# [1] 1 2 3 4 5 6 7 8 9 0
#
# $`6`
# [1] 1 8

Loop through a vector of vectors

When I loop through a vector of vectors, the result of each loop is several vectors. I would expect the result of each loop to be a vector. Please see the following example:
foo <- seq(from=1, to=5, by=1)
bar <- seq(from=6, to=10, by=1)
baz <- seq(from=11, to=15, by=1)
vects <- c(foo,bar,baz)
for(v in vects) {print(v)}
# [1] 1
# [1] 2
# [1] 3
# [1] 4
# [1] 5
# [1] 6
# [1] 7
# [1] 8
# [1] 9
# [1] 10
# [1] 11
# [1] 12
# [1] 13
# [1] 14
# [1] 15
This is odd as I would expect three vectors given it (should) iterate three times given the vector, c(foo,bar,baz). Something like:
# [1] 1 2 3 4 5
# [1] 6 7 8 9 10
# [1] 11 12 13 14 15
Can anyone explain why I am getting this result (15 vectors) and how to achieve the result I am looking for (3 vectors)?
Look at what vects is:
> vects
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
The c() joins (in this case) the three vectors, concatenating them into a single vector. In the for() loop, v takes on each values in vects in turn and prints it, hence the result you see.
Did you want a list of the three separate vectors? If so
> vects2 <- list(foo, bar, baz)
> for(v in vects2) {print(v)}
[1] 1 2 3 4 5
[1] 6 7 8 9 10
[1] 11 12 13 14 15
In other words, form a list of the vectors, not a combination of the vectors.
Substitute vects <- list(foo,bar,baz) for vects <- c(foo,bar,baz).
There is no such thing (really) as a vector of vectors.

Splitting a vector into two

How can I split a vector into two such that it selects a random sample for each new vector. But I always want to split in half. For instance
x <- 1:10
obj <- splitMyVector(x)
obj$a
> 5 3 9 7 10
obj$b
> 8 4 1 6 2
Note: the purpose for this is to do a split half reliability.
split(sample(x),letters[seq(length(x))%%2+1])
$a
[1] 9 7 10 4 2
$b
[1] 6 1 8 3 5

Resources