R detect file path automatically - r

Is there a way to make R detect the path of an input file in R script when running in R studio, automatically?
I have the following code
input.data <- read.xlsx("C:/Users/haha/Desktop/haha/input.xlsx", "input", header=F, rowIndex=NULL, startRow=1, endRow=21, colIndex=c(1:2))
If i were to share the script containing this code, the user will have to change the directory path for the input file before running the code.
I'd like to figure out a way to do this automatically such that the user is able to run the script without needing to change the directory's path.

You can get the directory of the script (basedir) automatically in this way and then use the directory to access the input file:
args <- commandArgs(trailingOnly = FALSE)
basedir <- dirname(sub("--file=", "", args[grep("--file=", args)]))
input.data <- read.xlsx(paste0(basedir, "input.xlsx"), "input", header=F, rowIndex=NULL, startRow=1, endRow=21, colIndex=c(1:2)))

You could use file.choose() to prompt the user to navigate the file.
It would look like this input.data <- read.xlsx(file.choose(), "input", header=F, rowIndex=NULL, startRow=1, endRow=21, colIndex=c(1:2))

Related

Read all files in specific folder in R

I am trying to read all files in a specific sub-folder of the wd. I have been able to add a for loop successfully, but the loop only looks at files within the wd. I thought the command line:
directory <- 'folder.I.want.to.look.in'
would enable this but the script still only looks in the wd. However, the above command does help create a list of the correct files. I have included the script below that I have written but not sure what I need to modify to aim it at a specific sub-folder.
directory <- 'folder.I.want.to.look.in'
files <- list.files(path = directory)
out_file <- read_excel("file.to.be.used.in.output", col_names = TRUE)
for (filename in files){
show(filename)
filepath <- paste0(filename)
## Import data
data <- read_excel(filepath, skip = 8, col_names = TRUE)
data <- data[, -c(6:8)]
further script
}
The further script is irrelevant to this question and works fine. I just can't get the loop to look over each file in files from directory. Many thanks in advance
Set your base directory, and then use it to create a vector of all the files with list.files, e.g.:
base_dir <- 'path/to/my/working/directory'
all_files <- paste0(base_dir, list.files(base_dir, recursive = TRUE))
Then just loop over all_files. By default, list.files has recursive = FALSE, i.e., it will only get the files and directory names of the directory you specify, rather than going into each subfolder. Setting recursive = TRUE will return the full filepath excluding your base directory, which is why we concatenate it with base_dir.

How to See Hidden Files in a File Dialog Using R?

Using RStudio on our Linux server, I am attempting to display a file dialog in R that allows the user to see hidden files (files that begin with a period {.*} that are visible with ls -a). I have tried the following file.choose() and rstudioapi::selectFile() with different options, but the hidden files remain hidden in the file dialog in each case:
myHiddenFile1a <- file.choose()
myHiddenFile1b <- file.choose(new = TRUE)
myHiddenFile2a <- rstudioapi::selectFile()
myHiddenFile2b <- rstudioapi::selectFile(existing = FALSE)
myHiddenFile2c <- rstudioapi::selectFile(filter = ".*")

In R, how can I call the same script for each folder in a parent directory?

I am trying to apply the same script to a few folders in the same directory. Separately the script works for each folder, but not when I use the following code:
parent.folder <- "C:/R_Files/Data/DICOM"
sub.folders <- list.dirs(parent.folder, recursive=TRUE)[-1]
r.scripts <- file.path(parent.folder, "general_extract.r")
# Run scripts in sub-folders
for(i in sub.foldes) {
source(i)
}
it shows me an error: Error in file(filename, "r", encoding = encoding) :
cannot open the connection
The script is here:
DCM <- readDICOM()
mAs <- extractHeader(DCM$hdr, "Exposure", FALSE)
mat = matrix(data=mAs, ncol=1)
write.table(mat, file="curve.txt", row.names=FALSE, col.names=FALSE,quote=FALSE)
Is it possible to rewrite the script which will apply "general_extract.r" to each folder in main directory and create the txt file with the specific name, related to the subfolder's name?
The best way to run the same set of commands for files in different folder is to change the working directory before re-sourcing the file each time. For example
parent.folder <- "C:/R_Files/Data/DICOM"
sub.folders <- list.dirs(parent.folder, recursive=TRUE)[-1]
r.scripts <- file.path(parent.folder, "general_extract.r")
# Run scripts in sub-folders
for(i in sub.folders) {
setwd(i)
source(r.scripts)
}
The setwd() will change R's working directory which includes where it looks to read and write files by default.

In R, opening an object saved to Excel through shell.exec

I would like to be able to open files quickly in Excel after saving them. I learned from R opening a specific worksheet in a excel workbook using shell.exec 1 on SO
On my Windows system, I can do so with the following code and could perhaps turn it into a function: saveOpen <_ function {... . However, I suspect there are better ways to accomplish this modest goal.
I would appreciate any suggestions to improve this multi-step effort.
# create tiny data frame
df <- data.frame(names = c("Alpha", "Baker"), cities = c("NYC", "Rome"))
# save the data frame to an Excel file in the working directory
save.xls(df, filename "test file.xlsx")
# I have to reenter the file name and add a forward slash for the paste() command below to create a proper file path
name <- "/test file.xlsx"
# add the working directory path to the file name
file <- paste0(getwd(), name)
# with shell and .exec for Windows, open the Excel file
shell.exec(file = file)
Do you just want to create a helper function to make this easier? How about
save.xls.and.open <- function(dataframe, filename, ...) {
save.xls(df, filename=filename, ...)
cmd <- file.path(getwd(), filename)
shell.exec(cmd)
}
then you just run
save.xls.and.open(df, filename ="testfile.xlsx")
I guess it doesn't seem like all that many steps to me.

Prompting user for multiple input files in R

I'm trying to do something I think should be straight forward enough, but so far I've been unable to figure it out (not surprisingly I'm a noob)...
I would like to be able to prompt a user for input file(s) in R. I've successfully used file.choose() to get a single file, but I would like to have the option of selecting more than one file at a time.
I'm trying to write a program that sucks in daily data files, with the same header and appends them into one large monthly file. I can do it in the console by importing the files individually, and then using rbind(file1, file2,...) but I need a script to automate the process. The number of files to append will not necessarily be constant between runs.
Thanks
Update: Here the code I came up that works for me, maybe it will be helpful to someone else as well
library (tcltk)
File.names <- tk_choose.files() #Prompts user for files to be combined
Num.Files <-NROW(File.names) # Gets number of files selected by user
# Create one large file by combining all files
Combined.file <- read.delim(File.names [1], header=TRUE, skip=2) #read in first file of list selected by user
for(i in 2:Num.Files){
temp <- read.delim(File.names [i], header=TRUE, skip=2) #temporary file reads in next file
Combined.file <-rbind(Combined.file, temp) #appends Combined file with the last file read in
i<-i+1
}
output.dir <- dirname(File.names [1]) #Finds directory of the files that were selected
setwd(output.dir) #Changes directory so output file is in same directory as input files
output <-readline(prompt = "Output Filename: ") #Prompts user for output file name
outfile.name <- paste(output, ".txt", sep="", collapse=NULL)
write.table(Combined.file, file= outfile.name, sep= "\t", col.names = TRUE, row.names=FALSE)` #write tab delimited text file in same dir that original files are in
Have you tried ?choose.files
Use a Windows file dialog to choose a list of zero or more files interactively.
If you are willing to type each file name, why not just loop over all the files like this:
filenames <- c("file1", "file2", "file3")
filecontents <- lapply(filenames, function(fname) {<insert code for reading file here>})
bigfile <- do.call(rbind, filecontents)
If your code must be interactive, you can use the readline function in a loop that will stop asking for more files when the user inputs an empty line:
getFilenames <- function() {
filenames <- list()
x <- readline("Filename: ")
while (x != "") {
filenames <- append(filenames, x)
x <- readline("Filename: ")
}
filenames
}

Resources