2016-08-03 50 views
2

我有我需要做計算的列中的數據。是否有可能使用以前的行值而不使用循環?例如。如果在第一列中的值是139,那麼計算最後5個值的中值以及上面5行的值和當前行中的值的百分比變化?使用先前行值無列循環的列計算

ID Data PF 
135 5  123 
136 4  141 
137 5  124 
138 6  200 
139 1  310 
140 2  141 
141 4  141 

所以這裏這個數據集,你會怎麼做:

  1. Data查找139ID
  2. 最後5行返回平均值(給出4.2)值的
  3. 回報表現PF 5行以上到當前值(給出152%

如果我會做一個循環,它看起來是這樣的:

for (i in 1:nrow(data)){ 
    if(data$ID == "139" & i>=3) 
    {data$New_column <- data[i,"PF"]/data[i-4,"PF"] - 1 
} 

的問題是,環路採用因太長許多數據點。 ID 139將在數據集中出現好幾次。

非常感謝。 Carlos

+0

請添加一個可重現的示例和預期輸出。 – Sotos

+2

查看'zoo'包中的'rollapply'。 – Tutuchan

+0

您能否定義您在性能上高於當前值的PF 5行中的值?它的意思是?它的中位數?在任何情況下,你都不會有139行以上的5行,只是4. – aichao

回答

0

這就是你想要的嗎?

ntest=139 
sol<-sapply(5:nrow(df),function(ii){#ii=6 
    tdf<-df[(ii-4):ii,] 
    if(tdf[5,1]==ntest) 
    c(row=ii,aberage=mean(tdf[,"Data"]),performance=round(100*tdf[5,"PF"]/tdf[1,"PF"]-1,0)) 
}) 
sol<- sol[ ! sapply(sol, is.null) ] #remove NULLs 
sol 

[[1]] 
     row  aberage performance 
     5.0   4.2  251.0 
0

這可能是一個不錯的開始:

mytext = "ID,Data,PF 
135,5,123 
136,4,141 
137,5,124 
138,6,200 
139,1,310 
140,2,141 
141,4,141" 

mydf <- read.table(text=mytext, header = T, sep = ",") 

do.call(rbind,lapply(mydf$ID[which(mydf$ID==139):nrow(mydf)], function(x) { 
    tempdf <- mydf[1:which(mydf$ID==x),] 
    data.frame(ID=x,Data=mean(tempdf$Data),PF=100*(tempdf[nrow(tempdf),"PF"]-tempdf[(nrow(tempdf)-4),"PF"])/tempdf[(nrow(tempdf)-4),"PF"]) 
})) 

ID  Data  PF 
139 4.200000 152.03252 
140 3.833333 0.00000 
141 3.857143 13.70968 

這裏的想法是:你把ID「開始,從139到結束s,不產生臨時使用他們每個人的lapply功能data.frame,其中包含特定的ID(包括ID本身)之上的所有行。然後你抓住Data列的平均值和PF列的變化率(即你所說的性能)。

2

正如指出的Tutuchacn和索托斯,使用包zoo獲得的最後N行Datamean(包括該行),您要查詢(假設你的數據在數據幀df):

library(zoo) 

ind <- which(df$ID==139)        ## this is the row you are querying 
N <- 5            ## here, N is 5 
res <- rollapply(df$Data, width=N, mean)[ind-(N-1)] 
print(res) 
## [1] 4.2 

rollapply(..., mean)返回width=N窗口化數據的滾動平均值。請注意,用於查詢rollapply的輸出的索引落後於N-1,因爲滾動均值是在該系列中向前應用的。

要按照指定的從PF獲取%的性能:

percent.performance <- function(x) { 
    z <- zoo(x)          ## create a zoo series 
    lz <- lag(z,4)          ## create the lag version 
    return(z/lz - 1) 
} 
res <- as.numeric(percent.performance(df$PF)[ind]) 
print(res) 
## [1] 1.520325 

在這裏,我們定義一個函數percent.performance返回你想要什麼的df所有行鍼對計算很有意義。然後我們使用ind提取我們想要的行並將其轉換爲數字。

希望這會有所幫助。

相關問題