Exporting a list of dataframes as csv - r

I have a list of dataframes which I want to export as csv. I tried :
for (i in listofdf){
write.csv(listofdf[i], file = paste(names(listofdf)[i],".csv", sep=""), row.names = FALSE)
}
and got : Error in listofdf[i] : invalid subscript type 'list'. I read that I am feeding a list data type into a process that expects a vector, and tried to apply the given solution : unlist(listofdf), but all I got is a massive list of numeric values that I don't know how to deal with.
Then I tried a solution found here, that works with the given example, but when I try to apply :
sapply(names(listofdf),
function (x) write.table(listofdf[x],
file = paste(names(listofdf)[x],".csv", sep=""),
row.names = FALSE))
but when I try it, it only exports one file named NA.csv. Do you know how to make any of those solutions work?

Your problem is how you're indexing your list object and names(listofdf)[i] isn't doing what you're thinking. Try This:
listofdf <- list(a = iris, b = iris, c = iris)
for (i in seq_along(listofdf)){
write.csv(listofdf[[i]], file = paste0(names(listofdf)[i], ".csv"), row.names = F)
}
Side note: the default separator for paste is a space. So you're putting a space before the ".csv" extension with your code. paste0 does not paste strings together with a space.
Alternatively, as mentioned you can use writexlsx by simply:
library(writexl)
write_xlsx(listofdfs, "output.xlsx")
This will create a file called "output.xlsx" with sheets that match names(listofdfs) and the proper values stored within those sheets.

Related

how can i make a loop in R system to save multiples excel files at the same time?

i have to save at least three diferent lists in trhee diferent execel files at the same time, in this case the name of the lists that will bacame files change only in the years, like this:
fluminense_2011
fluminense_2012
fluminense_2013
with this pointed i want to make a loop that can automate the process of saving the lists on excel files, but i dont know how to make that. I was tryng to save the lists in one vector and than triyng to aplly the follow formula:
data_names <- c("fluminense_2011", "fluminense_2012" , "fluminense_2014")
for(i in 2:length(data_names)) {
write.xlsx2(get(data_names[i]), paste0(my_path, "fluminense_bruto"),
row.names = FALSE, sheetName = data_names[i], append = TRUE)}
the problem is that i dont know how to change de formula above to adpapt for my problem
take a look at this answer.
dfs <- c('iris','cars')
lapply(dfs,function(x) xlsx::write.xlsx2(eval(as.symbol(x)), paste0(my_path, x,".xlsx"), row.names = FALSE, sheetName = x, append = TRUE))

Issues with user function/ map to read in and combine DBF files in R

I have written a function to read in a set of dbf files. Unfortunately, these files are very large, and I wouldn't want anyone to have to run them on my behalf.
readfun_dbf = function(path) {
test = read.dbf(path, as.is = TRUE) # dont convert to factors
test
}
dbfiles identifies the list of file names. map_dfr applies my function to the list of files and row binds them together. I've used very similar code to read in some text files, so I know the logic works.
dbfiles = list.files(pattern = "assign.dbf", full.names = F, recursive = T)
dbf_combined <- map_dfr(dbfiles, readfun_dbf)
When I run this, I get the error:
Error: Column `ASN_PCT` can't be converted from integer to character
So I ran the read.dbf command on all the files individually and noticed that some dfb files were being read in with all their feilds as characters, and some were being read in with some as integers and characters. I figured that map_dfr needs the fields to be of the same type to bind them, so I added the mutate_all command to my function--but it's still throwing the same error.
readfun_dbf = function(path) {
test = read.dbf(path, as.is = TRUE) # dont convert to factors
**mutate_all(test,as.character)**
test
}
Do you think the mixed field types are the issues? Or could it be something else? Any suggestions would be great!
Assign the value back to the object.
readfun_dbf = function(path) {
test = read.dbf(path, as.is = TRUE)
test <- dplyr::mutate_all(test,as.character)
return(test)
}
and then try :
dbf_combined <- purrr::map_dfr(dbfiles, readfun_dbf)

Unexpected error message while extracting vectors from a list

I want to extract vectors from a list of text files.
First define the correct "working directory" and then I generate a list that contains a the test files.
file.list <- list.files(pattern="*.txt", full.names=T)
Afterwards I format the data the right way.
datalist = lapply(file.list, FUN=read.table, header = F, sep = "\t", skip = 2)
And eventually I define the vectors which should be extracted.
cmbn = expand.grid(1:641, 1:977)
flen = length(datalist)
lapply(1:(nrow(cmbn)),function(t,lst,cmbn){
return(sapply(1:flen,function(i,t1,lst1,cmbn1){
return(lst1[[i]][cmbn1$Var1[t1],cmbn1$Var2[t1]])},t,lst,cmbn))}
,datalist,cmbn)
In the end I got as an output all the vectors. But how can I store them in a clever way? I want to be able to access the vectors individually.
The error message "incorrect number of dimensions" indicates that lst1[[i]] does not possess two dimensions. When dim returns NULL, it indicates that lst1[[i]] is not even a matrix nor array.
Try using str(lst1[[i]]) to take a look at the structure of the element. Is it vector? Is it something else? Or is it simply missing (NULL)?
When you know what is wrong, you can fix it. It could be reading an empty file, or that you are reading an index outside of the bounds of the list due to ??

How to delete specific rows from multiple columns

I am importing some columns from multiple csv files from R. I want to delete all the data after row 1472.
temp = list.files(pattern="*.csv") #Importing csv files
Normalyears<-c(temp[1],temp[2],temp[3],temp[5],temp[6],temp[7],temp[9],temp[10],temp[11],temp[13],temp[14],temp[15],temp[17],temp[18],temp[19],temp[21],temp[22],temp[23])
leapyears<-c(temp[4],temp[8],temp[12],temp[16],temp[20]) #separating csv files with based on leap years and normal years.
Importing only the second column of each csv file.
myfiles_Normalyears = lapply(Normalyears, read.delim,colClasses=c('NULL','numeric'),sep =",")
myfiles_leapyears = lapply(leapyears, read.delim,colClasses=c('NULL','numeric'),sep =",")
new.data.leapyears <- NULL
for(i in 1:length(myfiles_leapyears)) {
in.data <- read.table(if(is.null(myfiles_leapyears[i])),skip=c(1472:4399),sep=",")
new.data.leapyears <- rbind(new.data.leapyears, in.data)}
the loop is suppose to delete all the rows starting from 1472 to 4399.
Error: Error in read.table(myfiles_leapyears[i], skip = c(1472:4399), sep = ",") :
'file' must be a character string or connection
There is a nrows parameter to read.table, so why not try
read.table(myfiles_leapyears[i], nrows = 1471,sep=",")
Your myfiles_leapyears is a list. When subsetting a list, you need double brackets to access a single element, otherwise you just get a sublist of length 1.
So replace
myfiles_leapyears[i]
with
myfiles_leapyears[[i]]
that will at least take care of invalid subscript type 'list' errors. I'd second Josh W. that the nrows argument seems smarter than the skip argument.
Alternatively, if you define using sapply ("s" for simplify) instead of lapply ("l" for list), you'll probably be fine using [i]:
myfiles_leapyears = lapply(leapyears, read.delim,colClasses=c('NULL','numeric'),sep =",")
It is fine. I just turned the data from a list into a dataframe.
df <- as.data.frame(myfiles_leapyears,byrow=T)
leap_df<-head(df,-2928)

how to write multiple dataframe to a single csv file in a loop in R?

I would like to write a multiple dataframe "neighbours_dataframe" in a single CSV file :
I use this line to write the multiple dataframe to multiple file :
for(i in 1:vcount(karate)){
write.csv(neighbours_dataframe[[i]], file = as.character(V(karate3)$name[i]),row.names=FALSE)}
if I use this code:
for(i in 1:vcount(karate)){
write.csv(neighbours_dataframe[[i]], file = "karate3.csv",row.names=FALSE)}
this would give me just the last dataframe in the csv file :
I was wondering , How could I have a single CSV file which have all the dataframe in the way that the column header of the first dataframe just written to the csv file and all other data frame copied in a consecutive manner ?
thank you in advance
Two methods; the first is likely to be a little faster if neighbours_dataframe is a long list (though I haven't tested this).
Method 1: Convert the list of data frames to a single data frame first
As suggested by jbaums.
library(dplyr)
neighbours_dataframe_all <- rbind_all(neighbours_dataframe)
write.csv(neighbours_dataframe_all, "karate3.csv", row.names = FALSE)
Method 2: use a loop, appending
As suggested by Neal Fultz.
for(i in seq_along(neighbours_dataframe))
{
write.table(
neighbours_dataframe[[i]],
"karate3.csv",
append = i > 1,
sep = ",",
row.names = FALSE,
col.names = i == 1
)
}

Resources