Steveman30290
Steveman30290

Reputation: 561

Breaking Up a Vector, Using the Indices of Another Vector in R

I have vector a and vector b:

vector_a <- c(3,2,2,2,2)
vector_b <- c("3a","3b","3c", "2a","2b", "2ab", "2ac","2aab","2aac","2aaab","2aaac")

I want to break up vector_b according to vector_a. So for example, I want to break up vector_b into a list of 5 elements, using the length of each element in vector_a.

list_a <- list(one = c("3a","3b","3c"), 
               two = c("2a","2b"), 
               three = c("2ab","2ac"), 
               four = c("2aab","2aac"), 
               five = list(c("2aaab","2aaac"))

My initial involved looping over vector_a and trying to create a list that gives the indices I am trying to extract from vector b. So something of this sorts:

iteration_list <- vector(mode = "list", length = length(vector_a_))
counter <- 1
for(i in seq_along(vector_a)) { 
    iteration_list[[i]] <- counter:vector_a[[i]]
    counter <- counter + vector_a[[i]] 
    #Drawing a blank here as I see that the next iteration would go from 4:2
} 

I'm drawing a blank on the iteration portion, and I believe there has to be a vectorized function or something much more intuitive for this than what I am achieving. Thanks in advance!

Upvotes: 1

Views: 97

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 389135

We can use split in combination with cut/findInterval to divide data into groups based on position in vector_a.

split(vector_b, findInterval(seq_along(vector_b), 
                             cumsum(vector_a), left.open = TRUE))

#$`0`
#[1] "3a" "3b" "3c"

#$`1`
#[1] "2a" "2b"

#$`2`
#[1] "2ab" "2ac"

#$`3`
#[1] "2aab" "2aac"

#$`4`
#[1] "2aaab" "2aaac"

Upvotes: 1

akrun
akrun

Reputation: 887501

Here is an option with split. Create a grouping index based on replicating the sequence of 'vector_a' with the values in 'vector_a' and use that to split the 'vector_b'. If the names of the output needs to be 'one' to 'five', use `english'

library(english)
out <- split(vector_b, rep(seq_along(vector_a), vector_a))
names(out) <- english(seq_along(out))

-output

out
#$one
#[1] "3a" "3b" "3c"

#$two
#[1] "2a" "2b"

#$three
#[1] "2ab" "2ac"

#$four
#[1] "2aab" "2aac"

#$five
#[1] "2aaab" "2aaac"

If we want to use a for loop, while we subset the 'vector_b' based on index, add (+) the ith element of 'vector_a' with 'counter' and subtract 1 to assign those elements into the ith element of 'iteration_list'

counter <- 1
for(i in seq_along(vector_a)) {
   iteration_list[[i]] <- vector_b[counter:(vector_a[i] + counter-1)]
   counter <- counter + vector_a[i]
 }

-output

iteration_list
#[[1]]
#[1] "3a" "3b" "3c"

#[[2]]
#[1] "2a" "2b"

#[[3]]
#[1] "2ab" "2ac"

#[[4]]
#[1] "2aab" "2aac"

#[[5]]
#[1] "2aaab" "2aaac"

Upvotes: 1

Related Questions