2016-08-03 54 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提取我们想要的行并将其转换为数字。

希望这会有所帮助。