R-language Functions within lists
G'Day, I'm new to R and I have GOOGLED, read books and play a lot, but I can't figure out if what I'm doing is working. It compiles (no translator) and can be called (again no spit), it just doesn't want to do anything.
OK. SYNTAX.
I read that lists in R are OBJECTS of other languages. So for the Saturday and Sunday play, I was trying to get this to work.
GLOBAL <- list( counter = 1,
locked = FALSE,
important_value = 42,
copy_of_important_value = 42,
lock = function() { GLOBAL$locked = TRUE },
unlock = function() { GLOBAL$locked = FALSE },
is_locked = function() { return(GLOBAL$locked )},
visit = function() { GLOBAL$counter <- GLOBAL$counter + 1 })
> GLOBAL$locked
[1] FALSE
>
It works...
> GLOBAL$locked <- TRUE
> GLOBAL$locked
[1] TRUE
>
Is not
> GLOBAL$unlock()
> GLOBAL$locked
[1] TRUE
>
Does R have the value $ this or $ self construct? None of this is error-prone. He just doesn't seem to want to do anything! (functions). I suppose I could set up the function as a routing access table, but I thought the encapsulation would be great.
Second question. I have been told several times that R MUST keep all data in memory and that is a limitation. Does this enable swp on * NIX systems? I mean if you had a humungus matrix could you just add some kind of swap to make it fit?
Sorry for the dumb newbies
source to share
This can be done using proto-objects:
library(proto) # home page at http://r-proto.googlecode.com
GLOBAL <- proto( counter = 1,
locked = FALSE,
important_value = 42,
copy_of_important_value = 42,
lock = function(.) { .$locked = TRUE },
unlock = function(.) { .$locked = FALSE },
is_locked = function(.) { return(.$locked )},
visit = function(.) { .$counter <- .$counter + 1 })
GLOBAL$locked <- TRUE
GLOBAL$unlock()
GLOBAL$locked
## FALSE
source to share
The S3 way to do.
GLOBAL <- list(counter=1, locked=FALSE,
important_value=42, copy_of_important_value=42)
class(GLOBAL) <- "foo"
lock <- function(x, ...) UseMethod("lock")
lock.foo <- function(x)
{
x$locked <- TRUE
x
}
unlock <- function(x, ...) UseMethod("unlock")
unlock.foo <- function(x)
{
x$locked <- FALSE
x
}
is_locked <- function(x) x$locked
visit <- function(x)
{
x$counter <- x$counter + 1
x
}
GLOBAL <- lock(GLOBAL) # locked is now TRUE
GLOBAL <- unlock(GLOBAL) # locked is now FALSE
source to share
There's also a shell method
getGlobal <- function() {
counter <- 1
locked <- FALSE
important_value <- 42
list(
is_locked = function() locked,
lock = function() locked<<-TRUE,
unlock = function() locked<<-FALSE,
visit = function() {counter <<- counter + 1 }
)
}
And then you will use
GLOBAL <- getGlobal()
GLOBAL$is_locked()
# [1] FALSE
GLOBAL$lock()
GLOBAL$is_locked()
# [1] TRUE
This way, the state is stored in the application and getGlobal
returns a list of functions that you can use to access those variables that were not otherwise exposed.
source to share
Nothing happened because
-
R doesn't have any variables to jump to, because you have them,
=
doesn't mean the assignment happened internallylist()
. Thus, the only object in the global environment isGLOBAL
. The way you are using it=
right now is assigning names to the lists on the left, and they are subsequently accessed using the operator$
. -
Your functions don't return a value as you write them.
GLOBAL$locked()
will not return a value ifGLOBAL$locked <- FALSE
is all you have inside the body of the calling function. So I put it in parentheses and return our wish values.
So we just need to assign locked
to the global environment first, then <<-
reassign it.
I have shortened your list a little. Here's a look:
> GLOBAL <- list(locked = assign("locked", FALSE, parent.frame()),
lock = function() { (GLOBAL$locked <<- TRUE) },
unlock = function() { (GLOBAL$locked <<- 'HELLO') },
is_locked = function() { return(NULL) })
> GLOBAL$locked
[1] FALSE
> GLOBAL$lock()
[1] TRUE
> GLOBAL$unlock()
[1] "HELLO"
> GLOBAL$is_locked()
NULL
Yes, the list has its own environment, separate from the global environment. An example of this is
> l <- list(x = 5, y = 10)
> within(l, {
f <- function(x) 2 * x
})
$x
[1] 5
$y
[1] 10
$f
function (x)
2 * x
<environment: 0xb041278>
but we are currently in a global environment
> environment()
<environment: R_GlobalEnv>
It's funny that you have to ask this question, because yesterday I asked a question about the same thing . MrFlick gave a very good explanation on this matter.
source to share