首页 > 解决方案 > sapply 的替代品

问题描述

我在 R 中使用以下代码:

df$max_col<- sapply(df$col, function(x) ifelse(x == "", 0, strsplit(as.character(x), "", perl = TRUE)[[1]] %>% as.numeric %>% max(na.rm = T)))

这段代码基本上打破了像“123456”这样的字符串并将其转换为数字并从中返回最大值。现在,我有一列充满了这样的字符串,并且这段代码运行良好,直到数据量很小。但是当数据大小为 2500 万行(我目前正在处理)时,此代码变得非常慢。此代码是否有任何替代方法,通过它我可以从存储在新列中的字符串中获取最大值?

标签: rdplyrdata.tablesapply

解决方案


基于我上面的评论的答案(但我已经修改了代码以便它实际工作):

x <- c("123", "224", "221", "1912323", "445")
apply(sapply(1:9, function(p) grepl(p, x)), 1, function(k) max(which(k)))
# the above will work if 0 is never the largest  number in any cell

更通用的版本:

doit <- function(x) apply(sapply(0:9, function(p) grepl(p, x)), 1, function(k) max(which(k)))-1
x <- c("123", "224", "221", "1912323", "445", "000")
doit(x)
# [1] 3 4 2 9 5 0

这比使用 strsplit 的原始代码快大约 3 倍……但我确信还有改进的余地。嗯...实际上,我要再试strsplit一次:

doit3 <- function(.) sapply(strsplit(.,""), max)
doit3(x)
# [1] "3" "4" "2" "9" "5" "0"

这比我以前的方法快大约 5 倍。所以问题不在于sapplystrsplit在于其他组件。如果您需要将其转换为数字,请添加as.numeric到外层,这不会花费太多额外时间:

doit4 <- function(.) as.numeric(sapply(strsplit(.,""), max))
> doit4(x)
# [1] 3 4 2 9 5 0

推荐阅读