Reputation: 1968
demo <- data.frame(step = seq(1:5), x1 = sample(1:5, 5), x2 = sample(5:9, 5), xx = 0)
I have DF and would like to change one of its columns within "apply" but I do not want to use with global variable for this, thus, I am trying to pass environment inside FUN and assign variable within this environment.
# This method works but it looks like hardcode because I have to use global name "demo"
cycle <- function(k, d, e) { demo[k, 4] <<- k }
lapply(1:nrow(demo), cycle, demo, environment())
These methods do not work :
# In this case R shows error - "k" is not defined, although, it should work as a closure
cycle <- function(k, d, e) { with(e, d[k, 4] <- k) }
lapply(1:nrow(demo), cycle, demo, environment())
# I tried "assign" new value to DF but this did not change it, "xx" column is still 0
cycle <- function(k, d, e) { assign("d[k, 4]", k, envir = e) }
lapply(1:nrow(demo), cycle, demo, environment())
# This also does not change values in last column
cycle <- function(k, d, e) { assign(gsub("#", k, d), k, envir = e) }
lapply(1:nrow(demo), cycle, "demo[#,4]", environment())
Question : how to change specific column in DF from FUN without using global name of this DF?
Just a suggestion, maybe I incorrectly define environment?
Update : I need to use "lapply" because I need to put several actions into one function and iteratively execute it for each row, e.g. I may want to apply PCA on floating window in similar way :
DF = data.frame(...)
x1 x2 x3 res
1 2 3 0
4 5 6 0
7 8 9 0
for (k in 1:3)
{
x = DF[k:k + 2,]
pc <- princomp(x, ...)
ls <- loadings(pc) # or ls <- lm(x + 0)
values <- c(DF[k,1] * ls[1] + DF[k,2] * ls[2])
}
DF$res <- values
I need to execute this loop as a callback in "apply", how to get result (values) of this execution if I want to use "apply" instead of "for" loop?
As an example, I would like to have function like "applyWeeklySMA" in this article http://www.r-bloggers.com/structural-arbitrage-trading-the-equity-curve/ but I want to replace loop with "lapply", is this possible?
Upvotes: 0
Views: 44
Reputation: 12640
DF <- as.data.frame(matrix(1:15, ncol = 3))
pcl <- function(k, data) {
x <- data[k:(k + 2), ]
pc <- princomp(x)
load <- loadings(pc)
as.matrix(data[k, 1:2]) %*% load[1:2]
}
DF$res <- c(lapply(1:3, pcl, DF), rep(0, 2))
This is I think what you're trying to achieve. Note that the function pcl has no dependencies at all on the calling environment.
Upvotes: 1