This would be very useful to me. Can I sort the output of ls()
by date (last modified or something similar)?
Context: I have a very messy workspace full of various data.frames
, variables
and plots
. I need to find a data.frame
and I cannot remember what I called it, only that I was working on it recently. Hence ls()
sorted by date modified would help me work out what I called it.
To clarify: This is not a question about using history()
. I use history frequently and often save it when I think it might be required. In this case, history does not cover the period required, so I cannot find the data.frame
using history()
.
Additional: Aside from the stated task of finding a recently created data.frame
, it would be very useful, in general, to be able to sort ls()
according to date. I have well over 100 objects in the workspace that I have been working on for over 2 years (searching 2 years of history
does not sound fun either). If it were possible to sort these objects into a chronological order then I would have some idea of which were newer (and possibly edited) and which were older (and perhaps original).
I have attempted to improve my workflow by slowly moving individual objects into smaller, related workspaces. But this process will take time, and is essentially pointless (as I am nearing the end of data analysis anyway).
Something you might try is automating the logging of modifications to variables of interest using the makeActiveBinding
function. You could then use the log to sort the output of ls()
by modification time.
One caveat is that, using this method, tracking has to be set up before the variable is first used.
.change.log <- list()
track <- function(variable) {
makeActiveBinding(variable,
function(v)
if (! missing(v))
.change.log[[variable]] <<- c(.change.log[[variable]],
as.list(Sys.time())),
.GlobalEnv)
}
track('x')
x <- 1
.change.log
x <- 2
.change.log
Each time x
is modified, the anonymous function supplied to makeActiveBinding
gets called with v
equal to the new value. This function also gets called when x
is referenced, but with nothing supplied to v
in this case, hence the conditional with missing(v)
---we only want to update the log when the value changes.
After further consideration, a better alternative to makeActiveBinding
would be to install a modification logger via the function addTaskCallback
. The code below creates an automated logger that records timestamps by variable name every time the <-
operator is used at the top level.
# define a log maker function. This returns a new logger function
# bound with a fresh log.
mk.log <- function() {
log <- list()
# handler functions have to have these four args, but we only use the first.
function(expr, value, ok, visible) {
if (class(expr) == '<-') {
# convert the assignment call to a list, so the
# variable name can be extracted
call.list <- as.list(expr)
# extract the name of the variable being affected, and
# convert it to character, so we can use it as a list name
variable <- as.character(call.list[[2]])
# append a timestamp to the log for this variable
log[[variable]] <<- c(log[[variable]], list(Sys.time()))
}
# callback handlers need to return a bool
return(TRUE)
}
}
# assign the handler to .log, and install it.
addTaskCallback(.log <- mk.log(), name='log')
x <- 5
x <- 10
y <- 4
# read the log
environment(.log)$log
# $x
# $x[[1]]
# [1] "2013-01-25 10:24:26.581 EST"
#
# $x[[2]]
# [1] "2013-01-25 10:24:26.585 EST"
#
#
# $y
# $y[[1]]
# [1] "2013-01-25 10:24:26.589 EST"
Well, with a little creative hacking, you could write your own methods for your variables. E.g.:
datedmatrix<-function(data,nrow,ncol,...) {
output <- matrix(data, nrow=nrow,ncol=ncol,...)
attr(output,'create') <- date()
return(output)
}
No, but you should use the history
function to find its name through the latest commands you have run.
By default, history
will show the last 25 lines of code, but you can request more by doing:
history(max.show = 100)
There is also a hard limit on the number of lines you can show. It is equal to the value of the environment variable R_HISTSIZE
whose default is 512. But as the documentation says:
There is no limit on the number of lines of history retained during a session [...]
so you can do:
Sys.setenv("R_HISTSIZE" = 10000)
history(max.show = 10000)
and you should be able to see all your history since you started your session (assuming you ran less than 10000 lines of code.)
You could use ls.str(mode="list")
.
Example output:
b : 'data.frame': 1 obs. of 1 variable:
$ test: Factor w/ 1 level "a": 1
c : 'data.frame': 1 obs. of 1 variable:
$ x: num 1
I don't think the creation time is stored with any R objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With