Shoaibkhanz
Shoaibkhanz

Reputation: 2082

Create a list name column in a list of data frames

Data:

 vec.1 <- c(1, 2)
 vec.2 <- c(2, 3)
 df.1 <- data.frame(vec.1, vec.2)
 df.2 <- data.frame(vec.2, vec.1)
 my_list <- list(df.1, df.2)

I wish to create a list number column that sequences along each data frame indicating from which list they came from.

printing data list :

    [[1]]
   vec.1 vec.2
1     1     2
2     2     3

[[2]]
   vec.2 vec.1
1     2     1
2     3     2

Code:

funk <- function(x){
  index <- seq(x)
  linenum <- 
  cbind(x,index,linenum)
}

new.dat <- lapply(my_list, funk)

expected output :

[[1]]
  vec.1 vec.2 index listnum
1     1     2     1   1
2     2     3     2   1

[[2]]
  vec.2 vec.1 index listnum
1     2     1     1   2
2     3     2     2   2

currently I am facing difficulty creating this listnum column.

Upvotes: 1

Views: 57

Answers (3)

tpol
tpol

Reputation: 446

This is does what you were after

new_list <- lapply(1:length(my_list), function(x) 
            my_list[[x]] <- cbind(my_list[[x]][1],
                        my_list[[x]][2],
                        index = 1:length(my_list[[x]][[2]]),
                        listnum = rep(x, length(my_list[[x]][2]))))

new_list
# [[1]]
#   vec.1 vec.2 index listnum
# 1     1     2     1       1
# 2     2     3     2       1

# [[2]]
#   vec.2 vec.1 index listnum
# 1     2     1     1       2
# 2     3     2     2       2

Just realized this can be done without having to create new dataset. Once following is run,my_list contain required result.

lapply(1:length(my_list), function(x) 
                my_list[[x]] <<- cbind(my_list[[x]][1],
                            my_list[[x]][2],
                            index = 1:length(my_list[[x]][[2]]),
                            listnum = rep(x, length(my_list[[x]][2]))))

Upvotes: 1

tushaR
tushaR

Reputation: 3116

You can modify your function like this:

funk <- function(i,x){
index <- seq(x[[i]])
listnum <- i
cbind(x[[i]],index,listnum)
}

new.dat <- lapply(1:length(my_list), funk,my_list)

#>new.dat
#[[1]]
#    vec.1 vec.2 index listnum
#1     1     2     1       1
#2     2     3     2       1

#[[2]]
#    vec.2 vec.1 index listnum
#1     2     1     1       2
#2     3     2     2       2    

Upvotes: 1

akrun
akrun

Reputation: 887831

We can use transform to create the sequence column by looping through the list element and then the 'listnum' based on the sequence of length of 'my_list' with Map

Map(cbind, lapply(my_list, function(x) 
         transform(x, index = seq_len(nrow(x)))), listnum = seq_len(length(my_list)))

Or using tidyverse

library(dplyr)
library(purrr)
map2(my_list, seq_len(length(my_list)), ~mutate(.x, index = row_number(), listnum = .y))
#[[1]]
#   vec.1 vec.2 index listnum
#1     1     2     1       1
#2     2     3     2       1

#[[2]]
#   vec.2 vec.1 index listnum
#1     2     1     1       2
#2     3     2     2       2

Upvotes: 2

Related Questions