这是一个使用dplyr的解决方案,它非常适合处理这类问题。我创建了一些模拟的数据匹配你的例子:
library(dplyr)
## fake test data set
combo.test <- data.frame(
CUSTID = sample(rep(10000:999999, each=2), 800000, replace = F),
typeGas = sample(c(0,1), 800000, replace = T)
)
combo.test$typeElec <- ifelse(combo.test$typeGas == 0, 1, 0)
要分配“1” typeTest如果客户1两种typeElec和typeGas在(可能)不同行,您使用dplyr“GROUP_BY”功能,循环在data.frame中的每个不同的CUSTID上,然后“mutate”创建一个新的变量“typeTest”。 “ifelse”测试该CUSTID的typeElec或typeGas列中的“any”值是否为1。
# convert to tbl_df object, arrange by CUSTID, assign 1 to variable typeTest
# if CUSTID has values for 1 in both typeGas and typeElec
ptm <- proc.time()
combo.test <- combo.test %>% tbl_df() %>% arrange(CUSTID) %>%
group_by(CUSTID) %>%
mutate(typeTest = ifelse(any(typeGas == 1) & any(typeElec == 1), 1, 0)) %>%
ungroup()
proc.time() - ptm
“tbl_df()”的data.frame转换为一个很好的dplyr版本,并且管“%>%”运算符表示从每个函数的输出被传递到下一个。代码花了约10秒为我跑。
https://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html
UPDATE:对,我应该已经回答了你原来的问题,而不是给人一种替代方法。你的函数只有一个bug(第3行应该为CUSTID索引第1列而不是第2列)。速度问题与R处理矢量与数据帧的效率有关。这是一个很好的讨论:(Speed up the loop operation in R)。
elecOrGas2 <-function(myData) {
res <- numeric(nrow(myData)) # initialize a vector for 'typeTest'
for (i in 1:(nrow(myData)-1)) {
#if (myData[i,2]==myData[i+1,2])
if (myData[i,1]==myData[i+1,1]) { # correct index for CUSTID
if ((myData$typeGas[i]==myData$typeElec[i+1])|
(myData$typeElec[i]==myData$typeGas[i+1])) {
res[i] <- 1 # use
#myData$typeTest[i]=1
} else {
res[i]=0
}
} else {
res[i]=0
}
}
myData$typeTest <- res
return(myData)
}
library(dplyr)
combo.test <- data.frame(
CUSTID = sample(rep(10000:999999, each=2), 800000, replace = F),
typeGas = sample(c(0,1), 800000, replace = T)
)
combo.test$typeElec <- ifelse(combo.test$typeGas == 0, 1, 0)
combo.test <- arrange(combo.test, CUSTID) %>% tbl_df()
# test time using 1/10 of the data
# original function: 29 sec
system.time(elecOrGas(combo.test[1:80000,]) -> test1)
# updated vectorized function: 6 sec
system.time(elecOrGas2(combo.test[1:80000,]) -> test2)
你能描述一下你的循环试图做什么吗? – agenis
因为它是重复的,所以客户ID'12455'不应该为'typeTest'获得'1'吗? –
什么是您的数据维度?添加一些调试语句(每10或100行左右,尝试'message')来查看它是否正在计算。 –