Convert name of dataframe to string within a function - r

I have many dataframes which I want to run through a function which creates a directory with the name of that dataframe as the folder name.
I have tried:
Create_dir = function(data){
filename = deparse(substitute(data))
dir.create(filename, showWarnings = FALSE)
}
And
Create_dir = function(data){
list = lst(data, "x")
filename = names(list)[1]
dir.create(filename, showWarnings = FALSE)
}
And a few other methods which all work well outside functions, but inside the function they either name the folder "data" or don't work because filename equates to a list of strings of all the data in the dataframe.
Any help with this would be really appreciated.

The first function actually works, thanks, apologies.

Related

Using a string for an object name in a loop in R

I want to save several objects in a loop in separate files, but I have problems getting it right. Below is the code (a highly simplified example of the thing I am doing). I want the objects a2014 and b2014 to be saved to a2014.Rdata and b2014.Rdata. The code clearly does not work as the object parametername is saved and not the objects a2014 and b2014.
for (i in c("a","b")) {
data <- c(1,2)
parametername <- paste0(i,"2014")
assign(parametername, data)
save(parametername, file = paste0(i, "2014.Rdata")) # This is clearly not working
}
Any help is appreciated.
Cheers
Renger
You can pass the object name in list.
for (i in c("a","b")) {
data <- c(1,2)
parametername <- paste0(i,"2014")
assign(parametername, data)
save(list = parametername, file = paste0(i, "2014.Rdata"))
}

How to dynamically change names inside a for loop in usethis::use_data() R

This is my first time creating an R package. I am trying to include 39 different datasets into the pre-loaded data for my package. However the usethis::use_data() function which creates the .rda files takes an unquoted name only and not a variable. Therefore
data = dynamic_name_from_for_loop
it keeps creating a file data.rda instead of dynamic_name_from_for_loop.rda
library(usethis)
library(readtext)
library(tidyverse)
site_list = c('0034L','0081L','0089L','0166L','0220R','0236L','0307R',
'0333L','0414R','0434L','0445L','0450L','0476R','0501R','0515L',
'0566R','0629R','0651R','0688R','0701R','0817L','0846R','0876L',
'0917R','0938L','1044R','1194R','1227R','1233L','1377L','1396R',
'1459L','1726L','1833R','1946L','2023R','2133L','2201R','2255R')
for (i in 1:length(site_list)){
sitename = site_list[i]
filename = paste0('M:/Tools/GCsandbar/data-raw/',sitename,"sd.csv")
data = read.csv(filename, header = T)
df_name = paste0('RC',sitename,'sd')
assign(df_name,data)
usethis::use_data(data,name = df_name, overwrite = TRUE)
#file.rename(from = 'data/data.rda',to = paste('data/',df_name,'.rda')) ## this did not work
}
This just creates 39 instances of df_name.rda overwriting the previous one each time, instead of creating RC0034L.rda, RC0081L.rda, ....
use_data asks for unquoted names of the objects to be saved.
There is no argument called name, in the function, and as far as I can see, name = df-name is doing nothing.
Try do.call instead.
library(usethis)
library(readtext)
library(tidyverse)
site_list = c('0034L','0081L','0089L','0166L','0220R','0236L','0307R',
'0333L','0414R','0434L','0445L','0450L','0476R','0501R','0515L',
'0566R','0629R','0651R','0688R','0701R','0817L','0846R','0876L',
'0917R','0938L','1044R','1194R','1227R','1233L','1377L','1396R',
'1459L','1726L','1833R','1946L','2023R','2133L','2201R','2255R')
for (i in 1:length(site_list)){
sitename = site_list[i]
filename = paste0('M:/Tools/GCsandbar/data-raw/',sitename,"sd.csv")
data = read.csv(filename, header = T)
df_name = paste0('RC',sitename,'sd')
assign(df_name, data)
do.call("use_data", list(as.name(df_name), overwrite = TRUE))
}
In the loop, the use_data can be changed to use_data_raw
usethis::use_data_raw(df_name)

R rename files keeping part of original name

I'm trying to rename all files in a folder (about 7,000 files) files with just a portion of their original name.
The initial fip code is a 4 or 5 digit code that identifies counties, and is different for every file in the folder. The rest of the name in the original files is the state_county_lat_lon of every file.
For example:
Original name:
"5081_Illinois_Jefferson_-88.9255_38.3024_-88.75_38.25.wth"
"7083_Illinois_Jersey_-90.3424_39.0953_-90.25_39.25.wth"
"11085_Illinois_Jo_Daviess_-90.196_42.3686_-90.25_42.25.wth"
"13087_Illinois_Johnson_-88.8788_37.4559_-88.75_37.25.wth"
"17089_Illinois_Kane_-88.4342_41.9418_-88.25_41.75.wth"
And I need it to rename with just the initial code (fips):
"5081.wth"
"7083.wth"
"11085.wth"
"13087.wth"
"17089.wth"
I've tried by using the list.files and file.rename functions, but I do not know how to identify the code name out of he full name. Some kind of a "wildcard" could work, but don't know how to apply those properly because they all have the same pattern but differ in content.
This is what I've tried this far:
setwd("C:/Users/xxx")
Files <- list.files(path = "C:/Users/xxx", pattern = "fips_*.wth" all.files = TRUE)
newName <- paste("fips",".wth", sep = "")
for (x in length(Files)) {
file.rename(nFiles,newName)}
I've also tried with the "sub" function as follows:
setwd("C:/Users/xxxx")
Files <- list.files(path = "C:/Users/xxxx", all.files = TRUE)
for (x in length(Files)) {
sub("_*", ".wth", Files)}
but get Error in as.character(x) :
cannot coerce type 'closure' to vector of type 'character'
OR
setwd("C:/Users/xxxx")
Files <- list.files(path = "C:/Users/xxxx", all.files = TRUE)
for (x in length(Files)) {
sub("^(\\d+)_.*", "\\1.wth", file)}
Which runs without errors but does nothing to the names in the file.
I could use any help.
Thanks
Here is my example.
Preparation for data to use;
dir.create("test_dir")
data_sets <- c("5081_Illinois_Jefferson_-88.9255_38.3024_-88.75_38.25.wth",
"7083_Illinois_Jersey_-90.3424_39.0953_-90.25_39.25.wth",
"11085_Illinois_Jo_Daviess_-90.196_42.3686_-90.25_42.25.wth",
"13087_Illinois_Johnson_-88.8788_37.4559_-88.75_37.25.wth",
"17089_Illinois_Kane_-88.4342_41.9418_-88.25_41.75.wth")
setwd("test_dir")
file.create(data_sets)
Rename the files;
Files <- list.files(all.files = TRUE, pattern = ".wth")
newName <- sub("^(\\d+)_.*", "\\1.wth", Files)
file.rename(Files, newName)

R : name of an object stored in a variable

I have this little problem in R : I loaded a dataset, modified it and stored it in the variable "mean". Then I used an other variable "dataset" also containing this dataset
data<-read.table()
[...modification on data...]
mean<-data
dataset<-mean
I used the variable "dataset" in some other functions of my script, etc. and at the end I want to store in a file with the name "table_mean.csv"
Of course the command write.csv(tabCorr,file=paste("table_",dataset,".csv",sep=""))
nor the one with ...,quote(dataset)... do what I want...
Does anyone know how I can retrieve "mean" (as string) from "dataset" ?
(The aim would be that I could use this script for other purposes simply changing e.g. dataset<-variance)
Thank you in advance !
I think you are trying to do something like the following code does:
data1 <- 1:4
data2 <- 4:8
## Configuration ###
useThisDataSet <- "data2" # Change to "data1" to use other dataset.
currentDataSet <- get(x = useThisDataSet)
## Your data analysis.
result <- fivenum(currentDataSet)
## Save results.
write.csv(x = result, file = paste0("table_", useThisDataSet, ".csv"))
However, a better alternative would be to wrap your code into a function and pass in your data:
doAnalysis <- function(data, name) {
result <- fivenum(data)
write.csv(x = result, file = paste0("table_", name, ".csv"))
}
doAnalysis(data1, "data1")
If you always want to use the name of the object passed into the function as part of the filename, we can use non-standard evaluation to save some typing:
doAnalysisShort <- function(data) {
result <- fivenum(data)
write.csv(x = result, file = paste0("table_", substitute(data), ".csv"))
}
doAnalysisShort(data1)

Function to read in multiple delimited text files

Using this answer, I have created a function that should read in all the text datasets in a directory:
read.delims = function(dir, sep = "\t"){
# Make a list of all data frames in the "data" folder
list.data = list.files(dir, pattern = "*.(txt|TXT|csv|CSV)")
# Read them in
for (i in 1:length(list.data)) {
assign(list.data[i],
read.delim(paste(dir, list.data[i], sep = "/"),
sep = sep))
}
}
However, even though there are .txt and .csv files in the specified directory, no R objects get created (I'm guessing this happens because I'm using the read.delim within a function). How to correct this?
You can add the parameter envir in your assignment, like this :
read.delims = function(dir, sep = "\t"){
# Make a list of all data frames in the "data" folder
list.data = list.files(dir, pattern = "*.(txt|TXT|csv|CSV)")
# Read them in
for (i in 1:length(list.data)) {
assign(list.data[i],
read.delim(paste(dir, list.data[i], sep = "/"),
sep = sep),
envir=.GlobalEnv)
}
}
Doing this, your object will be created in the global environment and not just in the function environment
As I said in my comment, it is necessary to return() a value after assigning. I don't really see the point in using assign() though, so here it is with a simple for-loop, assuming you want your output to be a list of data frames.
Note that I changed the reading function to read.table() for personal convenience. You might want to adjust that.
read.delims <- function(dir, sep = "\t"){
# Make a list of all data frames in the "data" folder
list.data <- list.files(dir, pattern = "*.(txt|TXT|csv|CSV)")
list.out <- as.list(1:length(list.data))
# Read them in
for (i in 1:length(list.data)) {
list.out[[i]] <- read.table(paste(dir, list.data[i], sep = "/"), sep = sep)
}
return(list.out)
}
Maybe you should also add a $ to your regular expression.
Cheers.

Resources