【发布时间】:2014-01-30 03:12:03
【问题描述】:
我正在寻找加快代码速度的方法。我正在研究apply/ply 方法以及data.table。不幸的是,我遇到了问题。
这是一个小样本数据:
ids1 <- c(1, 1, 1, 1, 2, 2, 2, 2)
ids2 <- c(1, 2, 3, 4, 1, 2, 3, 4)
chars1 <- c("aa", " bb ", "__cc__", "dd ", "__ee", NA,NA, "n/a")
chars2 <- c("vv", "_ ww_", " xx ", "yy__", " zz", NA, "n/a", "n/a")
data <- data.frame(col1 = ids1, col2 = ids2,
col3 = chars1, col4 = chars2,
stringsAsFactors = FALSE)
这是一个使用循环的解决方案:
library("plyr")
cols_to_fix <- c("col3","col4")
for (i in 1:length(cols_to_fix)) {
data[,cols_to_fix[i]] <- gsub("_", "", data[,cols_to_fix[i]])
data[,cols_to_fix[i]] <- gsub(" ", "", data[,cols_to_fix[i]])
data[,cols_to_fix[i]] <- ifelse(data[,cols_to_fix[i]]=="n/a", NA, data[,cols_to_fix[i]])
}
我最初查看ddply,但我想使用的一些方法只使用向量。因此,我无法弄清楚如何在某些列中一一对应地处理 ddply。
另外,我一直在查看laply,但我想将原始data.frame 与更改一起返回。谁能帮我?谢谢。
根据之前的建议,这是我尝试从 plyr 包中使用的内容。
选项 1:
data[,cols_to_fix] <- aaply(data[,cols_to_fix],2, function(x){
x <- gsub("_", "", x,perl=TRUE)
x <- gsub(" ", "", x,perl=TRUE)
x <- ifelse(x=="n/a", NA, x)
},.progress = "text",.drop = FALSE)
选项 2:
data[,cols_to_fix] <- alply(data[,cols_to_fix],2, function(x){
x <- gsub("_", "", x,perl=TRUE)
x <- gsub(" ", "", x,perl=TRUE)
x <- ifelse(x=="n/a", NA, x)
},.progress = "text")
选项 3:
data[,cols_to_fix] <- adply(data[,cols_to_fix],2, function(x){
x <- gsub("_", "", x,perl=TRUE)
x <- gsub(" ", "", x,perl=TRUE)
x <- ifelse(x=="n/a", NA, x)
},.progress = "text")
这些都没有给我正确的答案。
apply 效果很好,但我的数据非常大,plyr 包中的进度条会非常好。再次感谢。
【问题讨论】:
-
“非常大”有多大?您能否提供与您的真实数据维度相对应的示例数据?当操作需要数小时才能完成时,需要进度条。这里唯一的瓶颈是
gsub和分配期间的大量副本(后者可以通过引用分配来避免)。提供真实的数据维度肯定会有所帮助。 -
@Arun 进度条对于 >5 秒的任务很有用,因为它可以帮助您校准需要多长时间。
标签: r data.table plyr apply