0
votes

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=".")}
return(act)}

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...

1
The 'mapply' function may be useful herebouncyball
Or Map which is a handy wrapper for mapply that always returns a list like lapply. Something like act_list <- Map(f, a_files, b_files, type = "b") should be pretty close.lmo
Can you not do it with two calls to mapply; mapply(f,a_files, type = "a"); mapply(f,b_files, type = "b")USER_1
Another approach is to create two functions, f_afile and f_bfile for the two types of files, lapply a_files and b_files to their respective functions, and then concatenate the two lists.Weihuang Wong

1 Answers

1
votes

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=".")
    }
    return(act)
}

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".