我正在尝试在R SAS样式库中实现,您可以在其中定义与目录对应的库对象,然后通过为库成员分配文件到该磁盘。
以下代码适用于已存在的文件。因此,如果您已经有一个包含文件的目录,您可以通过myLib$file
阅读它们并使用myLib$file <- value
写信给他们。我无法弄清楚做的是通过myLib$newfilename <- value
写一个新文件。
任何人都知道如何实现这个目标?
library(plyr)
# What this does:
# A function which creates an active binding to a given name, and using
# the given directory path. Upon access, the binding creates an environment
# with active bindings for each file in that directory which will use readRDS
# on access and saveRDS on change.
# What this doesn't do:
# Can't use this to write to a file that doesn't yet exist. If the directory
# has blah1.rdata and blah2.rdata, you can do myLib$blah3.rdata <- 1. Instead
# of writing to disk, this will simply assign the value of 1 into an the env
# returned by the outer active binding.
# What tried and failed to do:
# I tried to set this up so that the outer active binding catches where the
# user tries
lib <- function(libname,path){
# Assign the name libname as an active binding in the global environment
makeActiveBinding(
libname,
function(value){
if(missing(value)){
# If user is reading from binding, find all the files in the given
# path that use the .rdata extension, create an environment, and
# populate it with active bindings for each .rdata file which will
# read/write using readRDS/saveRDS.
regex <- "^.*\\.(rdata)$"
files <- list.files(
path=path,
pattern = regex,
ignore.case=TRUE
)
myEnv <- new.env()
myEnv$path <- path
l_ply(
seq_along(files),
function(i){
makeActiveBinding(
files[i],
function(value){
if(missing(value)){
readRDS(paste0(path,"/",files[i]))
}else{
saveRDS(value,paste0(path,"/",files[i]))
}
},
myEnv
)
})
return(myEnv)
}else{
# If the user is writing to a binding, this should be set to
# figure out what name the user is writing to, then do saveRDS
# to the given library's path using that name as a filename.
#
# Can't figure out how to make it work as I can't capture the
# name being assigned to from the call...
#
# Note that this code only triggers and is necessary in the
# case where the user is writing to a name that does not
# correspond to an already existing file in the given directory
#invisible(NULL)
}
},
.GlobalEnv
)
}
# Directory to use
myDirectory <- "./"
# Pre-populate a couple files
saveRDS(mtcars,paste0(myDirectory,"/","myCars.rdata"))
saveRDS(iris,paste0(myDirectory,"/","myPlants.rdata"))
# Initialize binding
lib("myLib",path = myDirectory)
# print object from disk
print(head(myLib$myCars.rdata))
# write over object using cars instead of mtcars
myLib$myCars.rdata <- cars
# This works! It prints cars now instead of mtcars even using readRDS
print(head(readRDS(paste0(myDirectory,"/","myCars.rdata"))))
print(head(myLib$myCars.rdata))
# Wish I could write to a file that doesn't yet exist, but don't
# know how to make it work
myLib$somethingelse.rdata <- 10