Reputation: 389
I was hoping that you guys could help me transition from loops to more r-language. I can't figure out how to do it, despite multiple resources. Perhaps I'm just missing something, so here I am asking for your help!
Problem:
I have a list with multiple elements for which I want to iterate through, search for specific key words, and if they are present, extract specific information in relation to those hits. Where the numerics after the abbreviations are time stamps. Is there a way to 1) do this with the apply family (I'm trying to become more efficient with R language); and 2) a more efficient way overall?
Thanks in advance!
Example:
list_a <- list(
"ENRTE 12:34 ONSCNE: 12:43 ENRTE: 13:34 ATHOSP: 14:23",
"ENRTE 13:34 ONSNE: 13:43 ENRTE: 23:23 ATHOSP: 12:32"
)
list_a[[1]][2] <- "ENRTE 23:23 ONSCNE: 14:32 ERNTE: 17:34 ATHOSP: 13:32"
list_a[[2]][2] <- "ENRTE: 12:23 ONSCNE: 17:34 ENRTE: 17:34 ATHOSP: 14:32"
list_a
[[1]]
[1] "ENRTE 12:34 ONSCNE: 12:43 ENRTE: 13:34 ATHOSP: 14:23" "ENRTE 23:23 ONSCNE: 14:32 ERNTE: 17:34 ATHOSP: 13:32"
[[2]]
[1] "ENRTE 13:34 ONSNE: 13:43 ENRTE: 23:23 ATHOSP: 12:32" "ENRTE: 12:23 ONSCNE: 17:34 ENRTE: 17:34 ATHOSP: 14:32"
Then my loop goes as:
k=1
enroute_list = list()
for(i in 1:length(list_a)){
for(j in 1:length(list_a[[i]]){
if(list_a[[i]] %>% str_extract("ENRTE") %>% is.element('ENRTE',.){
list_a[[j]][i] %>%
str_extract("(?<=\\/)[:digit:]{2}") -> hour_enrte
list_a[[j]][i] %>%
str_extract("(?<=\\:)[:digit:]{2}(?=\\:)") -> minute_enrte
list_a[[j]][i] %>%
str_extract("(?<=\\:)[:digit:]{2}(?!\\:)") -> second_enrte
hour_enrte_df <- data.frame(hour_enrte)
minute_enrte_df <- data.frame(minute_enrte)
second_enrte_df <- data.frame(second_enrte)
time_enroute <- cbind(hour_enrte_df, minute_enrte_df, second_enrte_df) %>%
unite(.,enroute,1:3, sep=":")}
while(k <= 10) {
enroute_list[[k]] <- time_enroute
k <- k+1
break
}
enrte <- bind_rows(enrte_list)
}
This loop searches 12 terms throughout the entirety of the list (several hundred elements) and extracts the relevant info and produces a data frame at the end that looks like:
type received dispatched enroute onscene enrhsp arrhsp avail closed
1 AH 19:19:22 19:21:35 19:28:39 19:32:51 19:44:20 19:48:03 19:29:06 20:18:39
My loop works just fine, but it is bugging me cause everywhere I read I hear "don't use loops in R" so I figured I would try to challenge myself and transition to the apply family, but it is more daunting than I thought it would be.
Thanks again!
Upvotes: 0
Views: 46
Reputation: 21532
There's less reason than you might think to switch to *apply
, unless you like extremely compact code. In most cases there's little or no time penalty, assuming you write the loop correctly(pre-allocate space, don't calculate things you don't need, etc.).
So, along with "when in doubt, reboot," you can put "don't use loops" into the Closet Of Rarely True Things. Unless you are using loops instead of the built-in vectorized capability of most functions. Example:
for (j in 1:100) x[j] = sin(y[j])
vs
x = sin(y)
Upvotes: 3