Home > Blockchain >  Combine even and odd lists using split() and append() in R
Combine even and odd lists using split() and append() in R

Time:01-23

Consider the following MWE:

x <- rnorm(100) # generate values
k <- 4 # number of groups

y <- split(x, 1:k) # split values into k groups
y

# combine even and odd lists
for (i in 1:length(y)) {
  for (j in 1:length(y)) {
    if ((i %% 2 == 1) && (j %% 2 == 0)) {
     res <- append(y[[i]], y[[j]])
    }
  }
}

res

The above works except

(1) only elements from lists 3 and 4 in y are included because values are being overwritten during the second pass of the for loop.

(2) I would like to modify the above loop so that res returns a list of lists (in the same way they are returned by split(). That is res should contain one list containing y[[1]] and y[[2]], along with a second list containing y[[3]] and y[[4]].

CodePudding user response:

What you are looking for:

split(y, gl(2,2))

If you do not know the length of y before hand use:

split(y, gl(length(y)/2,2))

If you want only odds and only evens:

split(y, 1:2)

CodePudding user response:

To fix issue (1), you can initialize the res variable as an empty list before the for loop and then use the c() function to combine the elements of y[[i]] and y[[j]] into a new list, which you can then append to res:

res <- list()
for (i in 1:length(y)) {
  for (j in 1:length(y)) {
    if ((i %% 2 == 1) && (j %% 2 == 0)) {
     res[[length(res) 1]] <- c(y[[i]], y[[j]])
    }
  }
}

This will add the elements of y[[i]] and y[[j]] to a new list, and append that list to the res variable, avoiding overwriting previous values.

To fix issue (2), you can change the condition of the second for loop, to only run for i 1 to length(y)

res <- list()
for (i in 1:(length(y)-1)) {
  for (j in (i 1):length(y)) {
    if ((i %% 2 == 1) && (j %% 2 == 0)) {
     res[[length(res) 1]] <- c(y[[i]], y[[j]])
    }
  }
}
  • Related