我有一個龐大的數據集,我想執行一些操作。用我目前的代碼(如下所示)需要超過3小時(尚未完成)。我通過在較小的數據集上的一些測試縮小到了這個嵌套循環,並且需要使用apply
系列函數中的一個來提高性能(希望)和代碼清潔度。R適用於嵌套循環
file <- read.csv("file.csv")
dates <- unique(file$date)
names <- unique(file$name)
data<-c()
mat<-matrix(,nrow=length(dates),ncol=length(names)) # store % change for all names
# loop for every person
for (i in 1:length(names)) {
data[[names[i]]] <- file[file$name == names[i],]
align = 0 # no data for some dates, need alignment score to align later on
# if this object does not start on the same date as the earliest date we know,
# then pad this object with a null row at the top
if (!rownames(mat)[1] %in% data[[names[i]]]$date) {
data[[names[i]]] <- rbind(c("0000-00-00",0,as.character(data[[names[i]]]$name[1]),NA,FALSE),data[[names[i]]])
}
# loop for every date, beginning at 2 because the first date will not be used
for (j in 2:length(dates)) {
if (!rownames(mat)[j] %in% data[[names[i]]]$date) {
mat[j,i] = NA
align <- align + 1
next
}
current <- as.numeric(data[[names[i]]]$price[j-align])
previous <- as.numeric(data[[names[i]]]$price[j-1-align])
# actions based on current and previous cell values
if (is.na(previous)) {
mat[j,i] <- NA
} else if (current == 0 & previous == 0) {
mat[j,i] <- 0
} else if (current == 0) {
mat[j,i] <- NA
} else if (previous == 0) {
mat[j,i] <- NA
} else {
mat[j,i] <- current/previous-1
}
}
}
文件看起來像:
date id name price paid
1 2001-01-01 1 redacted 0.00 TRUE
2 2001-01-02 2 redacted 0.05 TRUE
3 2001-01-03 1 redacted 200.0 FALSE
概要:
循環,我們每個人,對於存儲其中的數據在它自己的位置在一個名爲data
矩陣列表。人們不止一次出現(通過ID和姓名,但我們只是擔心現在的姓名),這將構成data
中每個矩陣的唯一行。
從這裏,我們檢查每個人的日期是否與最早已知的日期對齊,如果沒有,則用一個空行填充它們的矩陣。
現在我們循環查看每個人的每個日期,檢查他們的日期是否迭代到當前迭代的時間(如果沒有,則用NA填充並轉到下一個(見下面)),然後計算%這個人支付了多少錢,取決於之前的價值(0和NA會導致問題,所以我們需要在這裏陳述if
陳述)。如果他們在2000-01-01支付20美元,在2000-01-02支付40美元,那麼百分比變化是100%(顯示爲1),因爲他們支付了兩倍。
所以最終的結果mat
將類似於:
redacted redacted redacted
2001-01-01 NA NA NA
2001-01-02 1 0.3 0.2
2001-01-03 0.5 0 NA
誰能幫助?我已經嘗試了許多變體,其中沒有一個似乎能夠工作或使我更接近解決方案。我知道這是一個巨大的閱讀/問題,所以任何幫助或提示將不勝感激!
似乎我可能需要嵌套apply
,每個循環一個?
謝謝!
我沒看過整個職位,但我已經發現'數據= C()' - 不增長向量R,而是預先將矢量分配給最終大小或合理大小:'data = vector(mode ='list',length = 1000)'。你能改變這個併發布結果嗎? – Fernando
小問題 - 避免調用事物'數據',因爲有一個同名的函數'?data' – csgillespie
我懷疑你會得到一個答案,除非你給一些可用的大小的例子數據與虛擬名稱例如。 'dput(head(yourdata,50))'和你對'head(你的數據,50)'運行你的函數時得到的預期輸出......因爲它非常難以遵循你的「rundown」,特別是當結果列全部被編輯。把自己放在我們的鞋子裏。 –