如何在 R 数据帧中向量化具有多个可能输出的函数
How to vectorize a function with multiple possible outputs in an R dataframe
我正在尝试将函数应用于 R 中的 data.frame
列,以检测特定字符串值是否存在。有各种字符串模式,每一种都构成了自己的分类。该函数应创建一个新列,根据 dat$id
列中的字符串提供所述分类 (dat$id_class
)。
我依靠 stringr
和 dplyr
包来完成这项工作。具体来说,我正在使用 dplyr::mutate
来应用该功能。
这段代码运行并产生了我正在寻找的准确结果,但我正在寻找一种更快的解决方案(如果存在的话)。这显然是一个数据集有限的小规模示例,而在我非常大的数据集上采用同样的方法所花费的时间比预期的要长得多。
library(stringi)
library(dplyr)
library(stringr)
dat <- data.frame(
id = c(
sprintf("%s%s%s", stri_rand_strings(1000000, 5, '[A-Z]'),
stri_rand_strings(5, 4, '[0-9]'), stri_rand_strings(5, 1, '[A-Z]'))
))
classify <- function(x){
if(any(stringr::str_detect(x,pattern = c('AA','BB')))){
'class_1'
} else if (any(stringr::str_detect(x,pattern = c('AB','BA')))){
'class_2'
} else {
'class_3'
}
}
dat <- dat %>% rowwise() %>% mutate(id_class = classify(id))
很有可能这个问题已经得到解答,我只是没有找对地方,但值得一试。
感谢任何帮助!
使用矢量化的 case_when
而不是使用 if/else
执行 rowwise
更改模式 OR
(|
)
library(stringr)
library(dplyr)
system.time({
dat1 <- dat %>%
mutate(id_class = case_when(str_detect(id, 'AA|BB') ~'class_1',
str_detect(id, 'AB|BA') ~ 'class_2', TRUE ~ 'class_3'))
})
# user system elapsed
# 0.460 0.036 0.493
基于OP函数的计时
system.time({dat2 <- dat %>%
rowwise() %>%
mutate(id_class = classify(id))
})
# user system elapsed
# 31.927 0.303 32.891
-检查输出
> all.equal(dat1, as.data.frame(dat2), check.attributes = FALSE)
[1] TRUE
我正在尝试将函数应用于 R 中的 data.frame
列,以检测特定字符串值是否存在。有各种字符串模式,每一种都构成了自己的分类。该函数应创建一个新列,根据 dat$id
列中的字符串提供所述分类 (dat$id_class
)。
我依靠 stringr
和 dplyr
包来完成这项工作。具体来说,我正在使用 dplyr::mutate
来应用该功能。
这段代码运行并产生了我正在寻找的准确结果,但我正在寻找一种更快的解决方案(如果存在的话)。这显然是一个数据集有限的小规模示例,而在我非常大的数据集上采用同样的方法所花费的时间比预期的要长得多。
library(stringi)
library(dplyr)
library(stringr)
dat <- data.frame(
id = c(
sprintf("%s%s%s", stri_rand_strings(1000000, 5, '[A-Z]'),
stri_rand_strings(5, 4, '[0-9]'), stri_rand_strings(5, 1, '[A-Z]'))
))
classify <- function(x){
if(any(stringr::str_detect(x,pattern = c('AA','BB')))){
'class_1'
} else if (any(stringr::str_detect(x,pattern = c('AB','BA')))){
'class_2'
} else {
'class_3'
}
}
dat <- dat %>% rowwise() %>% mutate(id_class = classify(id))
很有可能这个问题已经得到解答,我只是没有找对地方,但值得一试。
感谢任何帮助!
使用矢量化的 case_when
而不是使用 if/else
执行 rowwise
更改模式 OR
(|
)
library(stringr)
library(dplyr)
system.time({
dat1 <- dat %>%
mutate(id_class = case_when(str_detect(id, 'AA|BB') ~'class_1',
str_detect(id, 'AB|BA') ~ 'class_2', TRUE ~ 'class_3'))
})
# user system elapsed
# 0.460 0.036 0.493
基于OP函数的计时
system.time({dat2 <- dat %>%
rowwise() %>%
mutate(id_class = classify(id))
})
# user system elapsed
# 31.927 0.303 32.891
-检查输出
> all.equal(dat1, as.data.frame(dat2), check.attributes = FALSE)
[1] TRUE