missgwolf
missgwolf

Reputation: 408

Extract and append data to new datasets in a for loop

I have (what I think) is a really simple question, but I can't figure out how to do it. I'm fairly new to lists, loops, etc.

I have a small dataset:

df <- c("one","two","three","four")
df <- as.data.frame(df)
df

I need to loop through this dataset and create a list of datasets, such that this is the outcome:

[[1]]
one

[[2]]
one
two

[[3]]
one
two
three

This is more or less as far as I've gotten:

blah <- list()

for(i in 1:3){
  blah[[i]]<- i
}

The length will be variable when I use this in the future, so I need to automate it in a loop. Otherwise, I would just do

one <- df[1,]
two <- df[2,]

list(one, rbind(one, two))

Any ideas?

Upvotes: 2

Views: 673

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 389355

You can try using lapply :

result <- lapply(seq(nrow(df)), function(x) df[seq_len(x), , drop = FALSE])
result

#[[1]]
#   df
#1 one

# [[2]]
#   df
#1 one
#2 two

#[[3]]
#     df
#1   one
#2   two
#3 three

#[[4]]
#     df
#1   one
#2   two
#3 three
#4  four

seq(nrow(df)) creates a sequence from 1 to number of rows in your data (which is 4 in this case). function(x) part is called as anonymous function where each value from 1 to 4 is passed to one by one. seq_len(x) creates a sequence from 1 to x i.e 1 to 1 in first iteration, 1 to 2 in second and so on. We use this sequence to subset the rows from dataframe (df[seq_len(x), ]). Since the dataframe has only 1 column when we subset it , it changes it to a vector. To avoid that we add drop = FALSE.

Upvotes: 2

hello_friend
hello_friend

Reputation: 5798

Base R solution:

# Coerce df vector of data.frame to character, store as new data.frame: str_df => data.frame 
str_df <- transform(df, df = as.character(df))

# Allocate some memory in order to split data into a list:  df_list => empty list
df_list <- vector("list", nrow(str_df))

# Split the string version of the data.frame into a list as required: 
# df_list => list of character vectors
df_list <- lapply(seq_len(nrow(str_df)), function(i){
    str_df[if(i == 1){1}else{1:i}, grep("df", names(str_df))]
  }
)

Data:

df <- c("one","two","three","four")
df <- as.data.frame(df)
df

Upvotes: 1

Related Questions