I'd like to use the value in each row of one column of a dataframe (filenames) as an argument in a function. This function imports data from a .ods file that has a matching filename, and extracts information into a new dataframe.
I'd like to apply the function to each filename in the table 'filenames', thus creating about 50 data frames. I want to append each of these data frames, I'd imagine using rbind, to get one dataframe out at the end.
I've written it for one filename, but am struggling to work out how to write it as a function that repeats iteratively through the list of filenames, then appends the resulting dataframes.
I've written an example below, any help very gratefully received!
map <- data.frame(well = c("A01", "A02", "A03", "B01", "B02", "B03", "C01", "C02", "C03", "A01", "A02", "A03", "B01", "B02", "B03", "C01", "C02", "C03"),
plate = c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2))
filenames <- data.frame(filenames = c("file1", "file2", "file3"),
plate = c(1, 1, 2))
firstdatetime <- as.POSIXct("2020-03-26 07:56:20 GMT")
activefile <- as.vector(filenames[1,1])
data <- data.frame(read.ods(activefile))
###for the purposes of this example, a sample data file is created below
data <- data.frame(datetime = "2020-03-26 13:04:38 GMT", one = c(2,4,6), two = c(4, 6, 6), three = c(5, 5, 2))
###
plate <- as.numeric(filenames$plate[match(activefile, filenames$filenames)])
datetime <- as.POSIXct(data$datetime[1])
time <- as.numeric(difftime(strptime(datetime, "%Y-%m-%d %H:%M:%S"),
strptime(firstdatetime, "%Y-%m-%d %H:%M:%S")))
temp <- plate
df <- subset(map, plate == temp)
df$filename <- activefile
df$time <- time
a570 <- data.frame(data[,-1])
a570 <- as.vector(t(a570))
df$a570 <- a570
###
#then repeat this for each filename in 'filenames', adding each dataframe to the bottom of the one before. The final output would be one big data frame.
hello_friend's answer shows what to do if you simply need to read in the files and rbind()
them. To me, this is not interesting as it is obviously a duplicate.
However, I'm not sure if it's a duplicate when you need to do some pre-processing first (although to some it may seem an obvious extension). What you need to do is make a function to pre-process.
I've simplified your example further and have two ODS files, file1.ods
with data
a b
1 1
and file2.ods
with data
a b
2 2
And for pre-processing I'll use the simpler task of adding 3 to the first value. We could do the following:
library(readODS)
filenames <- c("file1.ods", "file2.ods")
foo <- function(filename) {
res <- read_ods(filename)
res[1, 1] <- res[1, 1] + 3
return(res)
}
do.call("rbind", lapply(filenames, foo))
# a b
# 1 4 1
# 2 5 2
You can of course make the pre-processing done in foo()
as complex as you like (including setting names if need be, dealing with dates as I think you're doing, etc.).