Home > Software engineering >  How to apply one more for loop in R?
How to apply one more for loop in R?

Time:06-29

I would like to write a for loop in R style (lapply?) to avoid the following repetitive code.

df1$fusion <- apply(df1[, cols], 1, paste, collapse = "-" )
df2$fusion <- apply(df2[, cols], 1, paste, collapse = "-" )
df3$fusion <- apply(df3[, cols], 1, paste, collapse = "-" )
df4$fusion <- apply(df4[, cols], 1, paste, collapse = "-" )
df5$fusion <- apply(df5[, cols], 1, paste, collapse = "-" )
df6$fusion <- apply(df6[, cols], 1, paste, collapse = "-" )
df7$fusion <- apply(df7[, cols], 1, paste, collapse = "-" )
df8$fusion <- apply(df8[, cols], 1, paste, collapse = "-" )
df9$fusion <- apply(df9[, cols], 1, paste, collapse = "-" )
df10$fusion <- apply(df10[, cols], 1, paste, collapse = "-" )
df11$fusion <- apply(df11[, cols], 1, paste, collapse = "-" )
df12$fusion <- apply(df12[, cols], 1, paste, collapse = "-" )

How do I do it? Something like in shell script style?

df_ls=("df1 df2 df3 df4 df5 df6 df7 df8 df9 df10 df11 df12")

for i in $df_ls
do
${i}$fusion <- apply(${i}[, cols], 1, paste, collapse = "-" )
done

CodePudding user response:

With lists. For example in your case.

list_df_general <- list(df, df2,...,df12) # load your date frames
lista_new <- list() # list empty
for(i in 12){
  lista_new[[i]] <- apply(lista_df_general[[i]][, cols], 1, paste, collapse = "-" )
}

For browser inside list you should do

list_new[[1]] or list_new[[2]] with 3,4,...,12.

CodePudding user response:

You can use something like

my_Fun <- function(df, cols)
{
  df$fusion <- apply(df[, cols], 1, paste, collapse = "-" )
}

for(i in 1 : 12)
{
  variable_Name <- paste0("df", i)
  assign(x = variable_Name, value = my_Fun(df = get(x = variable_Name), cols = cols))
}

CodePudding user response:

You can use a combination of lapply and apply on the list of dataframes. This will return a list of dataframes.

df_ls <- mget(paste0("df", 1:12))

lapply(df_ls, function(x) {x$fusion <- apply(x[, cols], 1, paste, collapse = "-" ); x})

CodePudding user response:

Multiple data frames in a list are always handier, find them in the .GlobalEnv and put them into one using mget. Now we may use lapply to apply any function to this list; we will define an anonymous function that uses Reduce which conveniently does the looping job to paste0 over the rows and columns for us, and is fast.

df_lst <- mget(paste0('df', 1:n))  ## put DFs in list
cols <- paste0('X', 2:5)  ## define columns, say 2 to 5

res <- lapply(df_lst, function(df) {df$fusion <- Reduce(\(x, y) paste0(x, '-', y), df[cols]); df})

res
# $df1
#   X1 X2 X3 X4 X5  fusion
# 1  A  A  T  G  C A-T-G-C
# 2  A  T  T  C  G T-T-C-G
# 3  A  G  A  G  A G-A-G-A
# 
# $df2
#   X1 X2 X3 X4 X5  fusion
# 1  A  T  C  C  C T-C-C-C
# 2  T  T  A  G  A T-A-G-A
# 3  G  C  A  A  A C-A-A-A
# 
# $df3
#   X1 X2 X3 X4 X5  fusion
# 1  G  G  A  T  T G-A-T-T
# 2  T  C  T  C  T C-T-C-T
# 3  G  T  G  C  G T-G-C-G
# 
# $df4
#   X1 X2 X3 X4 X5  fusion
# 1  G  T  A  G  G T-A-G-G
# 2  G  A  G  T  C A-G-T-C
# 3  T  G  T  C  A G-T-C-A

If for some reason, you need the data frames in the .GlobalEnv you may use list2env(res, .GlobalEnv) thereafter (similar as I did with the example data below).


Data:

set.seed(42)
n <- 4
replicate(n, data.frame(matrix(sample(LETTERS[c(1, 20, 3, 7)], 15, replace=TRUE), 3, 5)), simplify=FALSE) |>
  setNames(paste0('df', seq_len(n))) |> list2env(.GlobalEnv)
  •  Tags:  
  • r
  • Related