预备:这个问题主要是教育价值,即使这种方法并不是完全最优的,它仍然完成了实际的任务。我的问题是下面的代码是否可以针对速度进行优化和/或实现更优雅。也许使用额外的软件包,如plyr或重塑。运行实际数据大约需要140秒,远高于模拟数据,因为一些原始行只包含NA,并且必须进行额外的检查。为了比较,模拟的数据在大约30秒内被处理。优化:将数据帧拆分为数据帧列表,每行转换数据
条件:数据集包含360个变量设定的12 30倍,让我们为它们命名V1_1,V1_2 ......(第一组),V2_1,V2_2 ...(第二组)等。每组12个变量包含二分(是/否)回答,实际上对应于职业状态。例如:工作(是/否),学习(是/否)等等,总共12个状态,重复30次。
任务:手头的任务是将每组12个二分变量重新编码为具有12个响应类别(例如工作,学习...)的单个变量。最终我们应该得到30个变量,每个变量有12个响应类别。
数据:我不能发布的实际数据集,但这里是一个很好的模拟近似:
randomRow <- function() {
# make a row with a single 1 and some NA's
sample(x=c(rep(0,9),1,NA,NA),size=12,replace=F)
}
# create a data frame with 12 variables and 1500 cases
makeDf <- function() {
data <- matrix(NA,ncol=12,nrow=1500)
for (i in 1:1500) {
data[i,] <- randomRow()
}
return(data)
}
mydata <- NULL
# combine 30 of these dataframes horizontally
for (i in 1:30) {
mydata <- cbind(mydata,makeDf())
}
mydata <- as.data.frame(mydata) # example data ready
我的解决办法:
# Divide the dataset into a list with 30 dataframes, each with 12 variables
S1 <- lapply(1:30,function(i) {
Z <- rep(1:30,each=12) # define selection vector
mydata[Z==i] # use selection vector to get groups of variables (x12)
})
recodeDf <- function(df) {
result <- as.numeric(apply(df,1,function(x) {
if (any(!is.na(df))) which(x == 1) else NA # return the position of "1" per row
})) # the if/else check is for the real data
return(result)
}
# Combine individual position vectors into a dataframe
final.df <- as.data.frame(do.call(cbind,lapply(S1,recodeDf)))
总而言之,有一个双*应用函数,一个跨越列表,另一个跨数据框行。这使它有点慢。有什么建议么?提前致谢。
(+1)非常好框的问题。 – Arun 2013-04-10 19:36:31