for循环和if语句r + preallocation

时间:2016-04-06 12:14:07

标签: r if-statement for-loop

如果EA $阶段的值为1,则新向量OCC中的等效位置必须为90.到目前为止,我有这个:

head(EA$phase)
[1] 1 1 1 1 2 2

OCC <- vector(mode = "list", length = 580) #Pre-allocate OCC
for(i in 1:length(EA$phase)) # For each element in EA$phase
{
  if (EA$phase[i]=="1"){OCC[i]=90} #If the value of EA$phase[1] is 1 then OCC[1]=90
  if (EA$phase[i]=="2"){OCC[i]=90}
  if (EA$phase[i]=="3"){OCC[i]=50}
  if (EA$phase[i]=="4"){OCC[i]=70}
  if (EA$phase[i]=="5"){OCC[i]=60}
  if (EA$phase[i]=="6"){OCC[i]=50}
  if (EA$phase[i]=="7"){OCC[i]=70}
  if (EA$phase[i]=="8"){OCC[i]=70}
  if (EA$phase[i]=="9"){OCC[i]=80}
  if (EA$phase[i]=="10"){OCC[i]=80}
}

但这不是某种方式。有没有办法使这更有效/更正确?一些技巧?

2 个答案:

答案 0 :(得分:3)

你可以不用for循环(没有预分配):

occ <- c(90, 90, 50, 70, 60,  50, 70, 70, 80, 80)
OCC <- occ[EA$phase]

最终您希望将结果放在数据框中:

EA$OCC <- occ[EA$phase]

使用的技术是间接索引:您有一个变量(在本例中为EA$phase),其值是向量的索引(在本例中为occ

答案 1 :(得分:2)

尝试一下:

data.table

EA_DT <- data.table(phase = c(1,2,1,2,1,3,7,5))

lookup_DT <- data.table(V1 = c(1,2,3,4,5,6,7), V2 = c(90,90,50,70,60,50,70))
res1 <- merge(EA_DT, lookup_DT, by.x = "phase", by.y = "V1")

lookup_DT2 <- data.table(phase = c(1,2,3,4,5,6,7), OCC = c(90,90,50,70,60,50,70))
setkey(EA_DT, phase)
res2 <- merge(EA_DT, lookup_DT2)

更多data.table

res3 <- EA_DT[lookup_DT, on = c(phase = "V1"), nomatch = 0L]
setkey(EA_DT, phase)
res4 <- EA_DT[lookup_DT2, nomatch = 0L]

data.frame

EA_DF <- data.frame(phase = c(1,2,1,2,1,3,7,5))

lookup_DF <- data.frame(V1 = c(1,2,3,4,5,6,7), V2 = c(90,90,50,70,60,50,70))
res5 <- merge(EA_DF, lookup_DF, by.x = "phase", by.y = "V1")  

lookup_DF2 <- data.frame(phase = c(1,2,3,4,5,6,7), OCC = c(90,90,50,70,60,50,70))
res6 <- merge(EA_DF, lookup_DF2)

还可以使用dplyr::left_join()等,您只需要与查找表进行左连接。

编辑:包含匹配列名的较短版本,如@jogo所建议。