Virginia Morera Pujol Virginia Morera Pujol - 1 year ago 53
R Question

Use of lapply with custom functions of several arguments

I am having trouble using lapply with a custom function I created, but it is a fairly specific function and I haven't been able to find an answer that suits me.

The function is quite long and does a lot of things, but I think I've managed to trim it down to a reproducible example that gives the error I am getting.

The thing is, I have a folder with two different types of files, that I want to load into R as elements of a list. They have more or less the same information, but they have different layout, different file extension, different almost everything, so the process to import them is different for each type.

The function goes like this:

f <- function(a_file, b_file, type){
if (type == "a"){act <- read.table(a_file, skip = 19, header = TRUE, sep = "", dec = ".")}
if (type == "b"){act <- read.table(b_file, header=FALSE, sep="\t", dec=".")}

Then I create vectors with the names of the two types of files I want to call, like this:

a_files <- dir(pattern=".deg")
b_files <- dir(pattern=".act")

And finally try to apply the function like this:

act_list <- lapply(a_files, f, b_files, type = "b")

which works if
type = "a"
, but fails for
type = "b"
, giving the error:

Error in file(file, "rt") : invalid 'description' argument

which I am pretty sure has to do with the fact that I am applying the function to only the "a_files" vector and not to "b_files", but I as much as I try I can't figure out a way to fix it...

Answer Source

There is a much simpler way to solve your problem.

First, define the function to have only one argument for the filename.
Then decide inside it what type of file it is and do the right type of read.

readFiles = function(file){
    if(grepl(file,pattern = "\\.deg")){
        act <- read.table(a_file, skip = 19, header = TRUE, sep = "", dec = ".")
    if(grepl(file,pattern = "\\.act")){
        act <- read.table(b_file, header=FALSE, sep="\t", dec=".")

Finally, you only have to call lapply on your files vector:

filesVector = dir(pattern = "(\\.act|\\.deg)")
result = lapply(filesVector, readFiles)

filesVector will return all files that contain ".act" or ".deg".
NOTE: Your pattern is not correct, since it will return files that contain any character followed by "act" or by "deg".