нужно векторизовать функцию на строку - PullRequest
1 голос
/ 26 июня 2019

У меня есть 300-килобайтный фрейм данных с таким столбцом:

   db$performance[1:10]
   [1] "1C1CCCCCCCCCCCCCCCCCCCCCC" "CCCCCCCCCCCCC"             
    "4321CCCCCCCCCCCCCCCCCCCCC" "321CCCCCCCCCCCCCCCCCCCCCC"
    [5] "CCCCCCCCCCCCCC"            "4321CCCCCCCCCCCCC0"  "211CCCCCCCCCCCCCCCCCCCCCC" "BCCCCCCCCC"     [9] "BCCCCCCCCC"                "8"       

Я хочу найти в каждой строке этого столбца и посчитать количество «4», которые встречаются в последних (справа налево) 18 символьных элементах. решение петли, которое у меня есть, явно плохое, так как оно очень медленное (6 минут и более). увидеть ниже. Как я могу векторизовать решение (используя apply и / или dplyr?)

спасибо!

substrRight <- function(x, n){
 substr(x, nchar(x)-n, nchar(x))
}

db$NewVar = NA

for (N in 1:nrow(db)){
db$NewVar[N] = str_count( substrRight(db$performance[N],18), "4")
}

1 Ответ

4 голосов
/ 26 июня 2019

str_count и substr уже векторизованы.Итак, напрямую примените функцию ко всему столбцу

library(stringr)
str_count(substrRight(db$performance, 18), "4") 
#[1] 0 0 0 0 0 1 0 0 0 0

Это должно быть достаточно быстро.Проверка времени на большом наборе данных

Тесты

db1 <- db[rep(seq_len(nrow(db)), 1e5),, drop = FALSE]

system.time({
out <- numeric(nrow(db1))
for (i in seq_len(nrow(db1))){
 out[i]= str_count( substrRight(db1$performance[i],18), "4")
}
})
# user  system elapsed 
# 14.699   0.104  14.755 
system.time({
sapply(db1$performance, function(x) str_count( substrRight(x,18), "4") )

})
# user  system elapsed 
# 14.267   0.075  14.299 
system.time({
str_count(substrRight(db1$performance, 18), "4") 

})
# user  system elapsed 
#  0.437   0.016   0.452 

data

db <- structure(list(performance = c("1C1CCCCCCCCCCCCCCCCCCCCCC", "CCCCCCCCCCCCC", 
"4321CCCCCCCCCCCCCCCCCCCCC", "321CCCCCCCCCCCCCCCCCCCCCC", "CCCCCCCCCCCCCC", 
"4321CCCCCCCCCCCCC0", "211CCCCCCCCCCCCCCCCCCCCCC", "BCCCCCCCCC", 
"BCCCCCCCCC", "8")), class = "data.frame", row.names = c(NA, 
-10L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...