简体   繁体   中英

Create vectors within lappy (or loop)

I would like to loop a function over a vector of characters. The function will create a vector or a list, and the name of each vector (list) will be taken from the vector of characters. For example.

# The data would look like:
fist second third
1    2     3
1    NA    3
1    2     3
1    2     NA
NA   2     3

# I want to create three lists/vectors such as

first <- c("1.pdf", "1.pdf", "1.pdf", "1.pdf")
second <- c("2.pdf", "2.pdf", "2.pdf", "2.pdf")
third <- c("3.pdf", "3.pdf", "3.pdf", "3.pdf")

# where, first, second, third, now are the names of the vectors. I tried the following way. 

vector_names <- c("first", "second", "third")

cleanNA <- function(x){
  x <- as.character(as.data.frame(t(data[paste0(x)])))
  x <- na.omit(x) # remove all NA observations.
  x <- paste0(x, ".pdf")
  return(x)
}
# I can do this by a vector length 1. 

name <- c("first")
assign(name, namef)
namef <- createlists(name)

# But once I do an lapply, it won't create the three vectors as I wanted. The lapply does run and returns what I want, but not create the three vectors. 

lapply(vector_names, cleanNA)

I've been searching for this type of questions many times and feel R doesn't really provide a good way to generate a new vector within a loop. Am I right? Thanks.

Here's a simplified version:

cleanNA <- function(data, x){
   x <- data[[x]]
   x <- na.omit(x) 
   x <- paste0(x, ".pdf")
   return(x)
   #Or a one-liner
   #paste0(na.omit(data[[x]]), '.pdf')
}

list_vec <- lapply(vector_names, cleanNA, data = data)
list_vec

#[[1]]
#[1] "1.pdf" "1.pdf" "1.pdf" "1.pdf"

#[[2]]
#[1] "2.pdf" "2.pdf" "2.pdf" "2.pdf"

#[[3]]
#[1] "3.pdf" "3.pdf" "3.pdf" "3.pdf"

It is better to keep data in a list so that it is easier to manage and avoids creating lot of objects in global environment. However, if you want them as separate vectors you can use list2env :

list_vec <- setNames(list_vec, vector_names)
list2env(list_vec, .GlobalEnv)

data

data <- structure(list(first = c(1L, 1L, 1L, 1L, NA), second = c(2L, 
NA, 2L, 2L, 2L), third = c(3L, 3L, 3L, NA, 3L)), class = "data.frame",
row.names = c(NA, -5L))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM