Skip to content

Instantly share code, notes, and snippets.

@Christoph999
Created April 28, 2016 07:41
Show Gist options
  • Save Christoph999/60056d6399cf8e93258ffe70251fe3a3 to your computer and use it in GitHub Desktop.
Save Christoph999/60056d6399cf8e93258ffe70251fe3a3 to your computer and use it in GitHub Desktop.
imsbasics::clc()
mysum <- function(dt, x1, y1) {
res <- x1+y1
return(res)
}
myfun <- function(dt, x1, y1) {
# Hadley Advanced R p. 74: If a name isn't defined inside a function R will
# look one level up and so on But here they are defined!
# res <- dt[dt$x1 == x1 & dt$y1 == y1] # Same result
res <- dt[.(x1, y1), nomatch = 0L]
return(res)
}
myfun2 <- function(dt, x1, y1) {
a <- x1
b <- y1
# res <- dt[dt$x1 == a & dt$y1 == b] # Same result
res <- dt[.(a, b), nomatch = 0L]
return(res)
}
myfun3 <- function(dt, x1, y1) {
# Hadley Advanced R p. 267:
# res <- dt[dt$x1 == x1 & dt$y1 == y1] # Same result
# r <- eval(c(x1, y1), parent.frame(), parent.frame())
# r <- get(c("x1", "y1"), environment())
# r <- get(c("x1", "y1"), parent.frame())
r <- get(c("x1", "y1"), environment(myfun3))
res <- dt[.(r), nomatch = 0L]
return(res)
}
dt <- data.table::data.table(x1 = c(1, 2, 1, 4), y1 = c(10, 11, 12, 13))
data.table::setkey(dt, x1, y1)
x1 <- 1
y1 <- 12
# Expected: res = 300. Due to lazy evaluation? ... OK
res <- mysum(dt, x1, y1)
# Expected: res2 = (1, 12). Get all! ... Not ok!
res2 <- myfun(dt, x1, y1)
# Expected: res3 = (1, 12). ... OK
res3 <- myfun2(dt, x1, y1)
# Expected: res2 = (1, 12). Get two entries ... Not ok!
res4 <- myfun3(dt, x1, y1)
@symbolrush
Copy link

So halb verstehe ich das.

res2: ist etwas komisch, aber ist halt so. die subset funktion auf dem data.table schaut zuerst in der data.table nach dem x1 bzw. y1 und findet die spalten und gibt die auch zurück. Nicht super eindeutig, allerdings finde ich die Schreibweise dt[.(x1, y1), nomatch = 0L] auch etwas verwirrlich.. Also: Gut haben wir das rausgefunden und in Zukunft umgehen wir das halt mit lokal eindeutigen Namen. Viele Orte, wo man solche Probleme hat gibt es meiner Erfahrung nach nicht..

res4: Macht genau, was ich erwarte. get() gibt dir ein Objekt im zu untersuchenden environment zurück. Die Anfrage mit c("x1","y1") wird also nur halb ausgewertet. Danach wird mit dem Wert von "x1" gematcht. Also alles korrekt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment