Fastest way of using conditions in for loop

Viewed 83

So for the dataset birthwt I want the percentage of low weight babies that are born from mothers that smoke and were under 20 years when given birth. In other words, I want how many <2600 of bwt (weight) are for age <20 and smoke == 1.

I run the next three chunks of code that actually gives you the correct answer:

 # new df with the conditions
new_df <- subset(birthwt, age<20 & smoke==1)

 #for loop to calculate the low weight

low_weight <- 0
for (i in 1:length(new_df$bwt)){
  if(bwt[i] < 2600){
    low_weight <- low_weight + 1
  }
}

 #low weight for the original dataset
low_weight_tot <- 0
attach(birthwt)
for (i in 1:length(birthwt$bwt)){
  if(bwt[i] < 2600){
    low_weight_tot <- low_weight_tot + 1
  }
}

print(low_weight/low_weight_tot)*100

But I find it very tedious, is there any other simpler way of doing this with loops?

Thanks!

4 Answers

You don't need loops for this:

library(dplyr)
birthwt %>% 
  summarise(perc = mean(age < 20 & smoke == 1 & bwt < 2600))

A single for loop is enough.

#df contains the birthwt data

lwt_tot <- 0
lwt_2600 <- 0

for(i in 1:nrow(df)){
  lwt_tot <- lwt_tot + 1

  if(df$age[i] < 20 & df$smoke[i] == 1 & df$bwt[i] < 2600){
    lwt_2600 <- lwt_2600 + 1
  }

}

print((lwt_2600/lwt_tot)*100)
#[1] 3.703704

I want the percentage of low weight babies that are born from mothers that smoke and were under 20 years when given birth

This suggests the following code:

birthwt %>% 
   filter(bwt<2600) %>%
   group_by(`young(<20)`=age<20, smoke) %>%
   summarise(n = n()) %>%
   ungroup() %>%
   mutate(pct=100*n/sum(n)) 

# A tibble: 4 x 4
  `young(<20)` smoke     n   pct
  <lgl>        <int> <int> <dbl>
1 FALSE            0    22  34.9
2 FALSE            1    25  39.7
3 TRUE             0     9  14.3
4 TRUE             1     7  11.1

The last line is your answer, which is the same as given by your code.

In base R, we can count number of people with age < 20 smoke = 1 and bwt < 2600 and divide it by number of people with bwt < 2600 overall.

with(birthwt, sum(age < 20 & smoke == 1 & bwt < 2600)/sum(bwt < 2600)) * 100
#[1] 11.11
Related