Write dataframe to a ".csv" file without specifying file path - r

Given this data frame as:
a <- 1:5
b <- 6:10
df <- data.frame(a,b)
df
Can I write to .csv file automatically without pre-creating such .csv file
write(df)
without specifying the file path (because I have no pre-created file) and r will create one automatically to save my data frame in my working directory?

If I got your question! you just use:
write.csv(df, "df.csv")

Write a custom function that converts object name into a filename and saves as ".csv":
myWrite <- function(x){
write.csv(x, file = paste0(deparse(substitute(x)), ".csv"))
}
myWrite(mtcars)
list.files(pattern = "mtcars")
# [1] "mtcars.csv"

Related

Corrupted/overwritten excel file with write_xlsx

I am using this code in R to change the name of the fourth column of an excel file (thanks to this: Change column name with file name of corresponding excel file), however the problem is that at the end the file is overwritten and it generates a corrupted excel file (Excel file format and extension don’t match). How it is possible to create a new excel file a the end (not overwritten) or do you have any other solution to not create a corrupted file?
filenames <- list.files(pattern = '\\.xlsx', full.names = TRUE)
lapply(filenames, function(x) {
#Read the data
data <- readxl::read_excel(x)
#Change the 4th column with filename
names(data)[4] <- tools::file_path_sans_ext(basename(x))
#Write the data back
writexl::write_xlsx(data, x)
})
You can use tools::file_path_sans_ext and tools:.file_ext to put together a new output filename. In the code below, I append the suffix _new to the file name before the file extension.
filenames <- list.files(pattern = '\\.xlsx', full.names = TRUE)
lapply(filenames, function(x) {
#Read the data
data <- readxl::read_excel(x)
#Change the 4th column with filename
y <- tools::file_path_sans_ext(basename(x))
names(data)[4] <- y
#Write the data back
ext <- tools::file_ext(x)
y <- paste0(y, "_new.", ext)
writexl::write_xlsx(data, y)
})

Picking data from all csv files placed at a location

I have several csv files at a common location. Each csv file has the same column names but different data. The names of these csv files are different. Can I write a code in R to read in the data from all the csv files and then put it in a single data frame? The names of the csv files keep differing so I wish to have a code such that I do not have to explicitly specify the names of the csv files. Thanks.
Have a look at list.files for listing all files at a location, read.csv for loading one file into R, and rbind to put them into a single data.frame.
The code could look like this (untested)
setwd(location)
fnames <- list.files()
csv <- lapply(fnames, read.csv)
result <- do.call(rbind, csv)
filelist <- list.files(pattern = "\\.csv") # reads only .csv files in a folder
allcsv.files <- list()
count <- 1
for (file in filelist) {
dat <- read.csv(file)
allcsv.files[[count]] <- dat
count <- count + 1
}
allfiles <- do.call(rbind.data.frame, allcsv.files)
setwd("common location")
f <- list.files()
d <- data.frame()
for(i in 1:length(f)){
file <- read.csv(f[i],stringsasFactors=F)
d <- rbind(d,file)
}
colnames(d) <- c("col1","col2")
write.csv(d,"combined.csv",row.names=F)

R - Dynamic reference to files for read csv

I would like to make a script that reads data from the correct folder. I have several lines in my code refering to the foldername, therefore I would like to make this dynamic. Is it possible to make the reference to a folder name dynamic? See below what I would like to do
# Clarifies the name of the folder, afterwards "Foldername" will be used as reference
FolderA <- Foldername
# Read csv to import the data from the selected location
data1 <- read.csv(file="c:/R/Foldername/datafile1.csv", header=TRUE, sep=",")
data2 <- read.csv(file="c:/R/Foldername/datafile2.csv", header=TRUE, sep=",")
I am trying to get the same result as what I would get with this code:
data1 <- read.csv(file="c:/R/FolderA/datafile1.csv", header=TRUE, sep=",")
data2 <- read.csv(file="c:/R/FolderA/datafile2.csv", header=TRUE, sep=",")
Can somebody please clarify how it would be possible to make this dynamic?
You could use paste0 for this:
FolderA <- "Foldername"
paste0("c:/R/", FolderA, "/datafile1.csv")
#[1] "c:/R/Foldername/datafile1.csv"
So in your case:
data1 <- read.csv(file=paste0("c:/R/", FolderA, "/datafile1.csv"), header=TRUE, sep=",")
A slight generalization of #LyzandeR's answer,
make_files <- function(directory, filenames) {
sprintf("C:/R/%s/%s", directory, filenames)
}
##
Files <- sprintf("file%i.csv", 1:3)
##
make_files("FolderA", Files)
#[1] "C:/R/FolderA/file1.csv" "C:/R/FolderA/file2.csv" "C:/R/FolderA/file3.csv"
you could also try the following method. The loop will create a list with output file, but if your files all have the same column names you could just rbind them together (method 2). This method will allow you to specify your folder, then use the list.files function to extract all files with extension ".csv". This way if you have many csv files in a folder you won't have to write them all out individually.
# Specify working directory or location of files:
FolderA = "c:/R/Foldername"
# identify all files with specific extension:
files = list.files(FolderA,pattern="*.csv")
Method 1 - Separate by lists
data = NULL
for(i in 1:length(files)){
data[[i]] = read.csv(files[i],header=F,stringsAsFactors=F)
}
Method 2 - single dataframe
data = NULL
for(i in 1:length(files)){
df = read.csv(files[i],header=F,stringsAsFactors=F)
data = rbind(data,df)
}

R script to read / execute many .csv file from command line and write all the results in a .csv file

I have many .csv files in a folder. I want to get the binning result from each of the .csv file one by one automatically by R scripting from command line, and one by one write the result of all files into result.csv file. For example, I have file01.csv, file02.csv, file03.csv, file04.csv, file05.csv. I want that first R script will read / execute file01.csv and write the result into result.csv file, then read / execute file02.csv and write result into result.csv, again read / execute file03.csv and write result into result.csv, and so on. This is like a loop on all the files, and I want to execute the R script from the command line.
Here is my starting R script:
data <- read.table("file01.csv",sep=",",header = T)
df.train <- data.frame(data)
library(smbinning) # Install if necessary
<p>#Analysis by dwell:</p>
df.train_amp <-
rbind(df.train)
res.bin <- smbinning(df=df.train_amp, y="cvflg",x="dwell")
res.bin #Result
<p># Analysis by pv</p>
df.train_amp <-
rbind(df.train)
res.bin <- smbinning(df=df.train_amp, y="cvflg",x="pv")
res.bin #Result
Any suggestion and support would be appreciated highly.
Thank
Firstly you will want to read in the files from your directory. Place all of your source files in the same source directory. I am assuming here that your CSV files all have the same shape. Also, I am doing nothing about headers here.
directory <- "C://temp" ## for example
filenames <- list.files(directory, pattern = "*.csv", full.names = TRUE)
# If you need full paths then change the above to
# filenames <- list.files(directory, pattern = "*.csv", full.names = TRUE)
bigDF <- data.frame()
for (f in 1:length(filenames)){
tmp <- read.csv(paste(filenames[f]), stringsAsFactors = FALSE)
bigDF <- rbind(bigDF, tmp)
}
This will add the rows in tmp to bigDF for each read, and should result in final bigDF.
To write the df to a csv is trivial in R as well. Anything like
# Write to a file, suppress row names
write.csv(bigDF, "myData.csv", row.names=FALSE)
# Same, except that instead of "NA", output blank cells
write.csv(bigDF, "myData.csv", row.names=FALSE, na="")
# Use tabs, suppress row names and column names
write.table(bigDF, "myData.csv", sep="\t", row.names=FALSE, col.names=FALSE)
Finally I find the above problem can be solved as follows:
library(smbinning) #Install if necessary。
files <- list.files(pattern = ".csv") ## creates a vector with all files names in your folder
cutpoint <- rep(0,length(files))
for(i in 1:length(files)){
data <- read.csv(files[i],header=T)
df.train <- data.frame(data)
df.train_amp <- rbind(df.train,df.train,df.train,df.train,df.train,df.train,df.train,df.train) # Just to multiply the data
cutpoint[i] <- smbinning(df=df.train_amp, y="cvflg",x="dwell") # smbinning is calculated here
}
result <- cbind(files,cutpoint) # Produce details results
result <- cbind(files,bands) # Produce bands results
write.csv(result,"result_dwell.csv") # write result into csv file

How to append multiple files in R

I'm trying to read a list of files and append them into a new file with all the records. I do not intend to change anything in the original files. I've tried couple of methods.
Method 1: This methods creates a new file but at each iteration the previous file gets added again. Because I'm binding the data frame recursively.
files <- list.files(pattern = "\\.csv$")
#temparary data frame to load the contents on the current file
temp_df <- data.frame(ModelName = character(), Object = character(),stringsAsFactors = F)
#reading each file within the range and append them to create one file
for (i in 1:length(files)){
#read the file
currentFile = read.csv(files[i])
#Append the current file
temp_df = rbind(temp_df, currentFile)
}
#writing the appended file
write.csv(temp_df,"Models_appended.csv",row.names = F,quote = F)
Method 2: I got this method from Rbloggers . This methods won't write to a new file but keeps on modifying the original file.
multmerge = function(){
filenames= list.files(pattern = "\\.csv$")
datalist = lapply(filenames, function(x){read.csv(file=x,header=T)})
Reduce(function(x,y) {merge(x,y)}, temp_df)
}
Can someone advice me on how to achieve my goal?
it could look like this:
files <- list.files(pattern = "\\.csv$")
DF <- read.csv(files[1])
#reading each file within the range and append them to create one file
for (f in files[-1]){
df <- read.csv(f) # read the file
DF <- rbind(DF, df) # append the current file
}
#writing the appended file
write.csv(DF, "Models_appended.csv", row.names=FALSE, quote=FALSE)
or short:
files <- list.files(pattern = "\\.csv$")
DF <- read.csv(files[1])
for (f in files[-1]) DF <- rbind(DF, read.csv(f))
write.csv(DF, "Models_appended.csv", row.names=FALSE, quote=FALSE)
You can use this to load everything into one data set.
dataset <- do.call("rbind", lapply(file.list, FUN = function(file) {
read.table(file, header=TRUE, sep="\t")
}))
And then just save with write.csv.
Or you could go ahead and use shell commands in R:
system2("cat", args = "*.csv", stdout = "appendedfiles.csv")
This would be for unix based systems; I'm not sure what you would do for windows.
Try this for your ListOfFileNames:
ListOfFileNames<-list.files(pattern=".txt")
outFile <- file("all.txt", "w")
for (i in ListOfFileNames){
x <- readLines(i)
writeLines(x, outFile) # in the link the 1st and last line are skipped
}
close(outFile)
Source: https://r.789695.n4.nabble.com/R-Read-multiple-text-files-and-combine-into-single-file-td817344.html
There's an easy answer with rbind_list() now!
For instance:
dataFiles = map(Sys.glob("*.csv"), read.csv)
or however you're reading the files into a list
dat = rbind_list(dataFiles)
and dat will be what you're looking for!
If using Windows, it's easy to do this using the command prompt.
Start -> Run -> type "cmd" and hit return key
cd <path to folder>
copy /b *.txt <outputname>.txt
Concrete example:
cd C:\User\danny\docs\folder_with_txt files
copy /b *.txt concatenated.txt
Note that if you're changing drive letters to do this before cd
D:\> c:
C:\> cd C:\User\danny\docs\folder_with_txt files
copy /b *.txt concatenated.txt

Resources