2013-06-30 128 views
2

我正在使用for循環來替換使用mycons矢量的myarray元素的子集。每列中的子集將從mydates直到結束。有沒有其他的for循環?替代for循環用於替換矩陣中元素的子集中元素的位於R中的元素

mydates <- as.Date(c('2013-06-05','2013-06-16','2013-06-22')) 
mycons <- c(0.5,1/7,0.25) 
dates <- seq(as.Date('2013-06-01'),Sys.Date(),"days") 
myarray <- matrix(rep(1,length(dates)*length(mydates)),length(dates),length(mydates)) 

for (i in 1:length(mycons)) { 
    myarray[which(dates>mydates[i]),i] <- mycons[i] 
} 
+1

這是實際數據?或者這是一個簡化版本?因爲正如所寫的,它既快速又可能根本不需要'for'循環,因爲你似乎只是以一種相當直接的方式重新編碼你的數據。 – Thomas

+0

那麼,你需要幫助那個錯誤嗎?如果是這樣,請更新您的問題。或者,你是否想談談如何生成myarray矩陣? – Thomas

+0

@Thomas對不起,我雖然理解你的觀點,但現在我不能讓代碼工作,如果刪除'for'循環。如果你能以不同的方式幫助我生成「myarray」,我將不勝感激。 – nopeva

回答

1

你在比較的項目是不同類別的:性格和日期。 (我得到充滿1的整個矩陣)

試試這個:

mydates <- as.Date(mydates) # then the comparisons will more sensible 

它得到一個量化的答案,我使出了使用outer和重新排列的邏輯有點創建一個矩陣「新」的價值觀,然後將失敗的項目回1 strating值:

myarray2 <-matrix(mycons, 
       nrow=length(dates), ncol=length(mydates), byrow=TRUE) 
myarray2[ outer(dates, mydates, "<=") ] <- 1 
myarray2 

我嘗試使用mapply想我可以做這樣的事情從兩個序列通過「並行的項目」,但也沒有辦法,我可以得到「我」索引要抓住。

mapply(function(x,y) {myarray[i , ] <- y[x>dates]} , mydates, mycons) 

的for循環的典型返工:你幾乎可以隨時重建一個for循環爲sapply操作:

sapply(1:length(mycons), function(idx){ 
      myarray[which(dates>mydates[idx]),idx] <- mycons[idx]; myarray[,idx]}) 

我懷疑有人可以構建一個sweep操作,將做到這一點,但我還沒有真正收穫sweep呢。

如果你想採取@ Ferdinand.Kraft是建議建立相同的長度myarray中的向量的路徑,但留下來的obj[cond] <- value範式內,則做到這一點:

myarray[ outer(dates, mydates, ">") ] <- 
     rep(mycons, each=length(dates))[ outer(dates, mydates, ">")] 

這是一個例證通過將相同的條件應用於<-操作的兩側來使用條件分配。它可以很快。

+0

謝謝我更新了代碼。你知道這個for循環的替代嗎? – nopeva

+0

我可以想到一個可能的等效調用'mapply',但我不明白你爲什麼需要。對於這種操作,「循環」的速度同樣快。 –

+0

感謝您的幫助。我正在學習,並且經常讀到,由於內存問題,建議使用矢量化而不是循環。雖然循環在這種情況下會更好,但如果不是太複雜,你會介意幫助使用「mapply」版本嗎?它會讓我明白它是如何工作的。 – nopeva

1

您可以使用此:

myarray <- ifelse(outer(dates, mydates, `>`), rep(mycons, each=length(dates)), 1) 
+0

感謝這樣一個好的解決方案。 – nopeva