2015-06-27 69 views
0
demo <- data.frame(step = seq(1:5), x1 = sample(1:5, 5), x2 = sample(5:9, 5), xx = 0) 

我有DF並想在「apply」中改變它的一個列,但是我不想爲此使用全局變量,因此我試圖通過FUN內的環境並在此環境中分配變量。Closure在「with」裏面不起作用

# 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()) 

這些方法都不奏效:

# 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()) 

問題:如何在DF從FUN更改特定的列不使用這個DF的全局名稱?

只是一個建議,也許我錯誤地定義了環境?

更新:我需要使用「lapply」,因爲我需要將多個操作放入一個函數中,並對每一行迭代執行它,例如,我可能要在浮動窗口中類似的方式適用PCA:

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 

我需要在「應用」來執行這個循環的回調,如何得到這個執行的結果(值),如果我想用「應用「而不是」爲「循環?

作爲一個例子,我想在這篇文章http://www.r-bloggers.com/structural-arbitrage-trading-the-equity-curve/有「applyWeeklySMA」這樣的函數,但是我想用「lapply」代替循環,這可能嗎?

回答

1
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)) 

這是我想你想要達到的目標。請注意,函數pcl在調用環境中完全沒有依賴關係。

+0

謝謝,它似乎在工作,這裏唯一不清楚的事情是爲什麼我們需要在「lapply」結尾處做rep(0,2)? – Anonymous

+1

@你的data.frame有5行,但你的'lapply'輸出只有3。'rep'是在結尾添加幾個零。 「NA」是另一種選擇。 –

相關問題