0

I am trying to calculate the total price for China and US location using for loop :

Please refer below sample data-frame and code :

z <- data.frame(location = c("china", "china", "US", "US" ), quantity = c(100, 200, 100, 200))

## Calculate Total price, considering price for one quanity is $1 for china and $3 for US

for row in 1:nrow(z) {

  l <- z[row, "location"]

  q <- z[row, "quanity"]

  ifelse (l == "china", 

          z$total <- (z$quantity * 1),

          z$total <- (z$quantity * 3)) 
pralhad
  • 29
  • 1
  • 7

4 Answers4

3

In R, most of the time you can do away without loops. If you have only 2 locations as shown then in this case, you can also get away with ifelse. Try

transform(z, total = quantity * c(1, 3)[(location != "china") + 1])

#  location quantity total
#1    china      100   100
#2    china      200   200
#3       US      100   300
#4       US      200   600

If you have multiple such countries then you can also use case_when from dplyr

library(dplyr)
z %>%
  mutate(total = case_when(location == "china"~quantity, 
                           location == "US"~quantity * 3, 
                           ....more countries))
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
2

You do not need a loop at all

library(dplyr)

z <- data.frame(location = c("china", "china", "US", "US" ),
                quantity = c(100, 200, 100, 200))


z %>% group_by(location) %>%
  summarise(sum_quantity = quantity %>% sum) %>% 
  mutate(total = if_else(location == 'china',
                                sum_quantity,
                                sum_quantity * 3))
#> # A tibble: 2 x 3
#>   location sum_quantity total
#>   <fct>           <dbl> <dbl>
#> 1 china             300   300
#> 2 US                300   900


# the ideal world

new_z <- data.frame(location = c("china", "china", "US", "US" ),
                quantity = c(100, 200, 100, 200),
                value_rate = c(1,1,3,3))

new_z %>% group_by(location) %>%
  summarise(sum_quantity = (quantity * value_rate) %>% sum)
#> # A tibble: 2 x 2
#>   location sum_quantity
#>   <fct>           <dbl>
#> 1 china             300
#> 2 US                900

Created on 2020-01-07 by the reprex package (v0.3.0)

Bruno
  • 4,109
  • 1
  • 9
  • 27
1

I do agree with other answers that in this particular situation a for loop is probably an overkill and below is my attempt to provide you with a tidyverse solution. However, if you do want to stick to a loop paradigm, look into For each row in an R dataframe

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(magrittr)
z <- data.frame(location = c("china", "china", "US", "US" ), quantity = c(100, 200, 100, 200))
z %>% 
  mutate(price = ifelse(location == "china", 1, 3)) %>% 
  group_by(location) %>% 
  summarise(total = sum(quantity * price))
#> # A tibble: 2 x 2
#>   location total
#>   <fct>    <dbl>
#> 1 china      300
#> 2 US         900

Created on 2020-01-07 by the reprex package (v0.3.0.9000)

PaulDong
  • 711
  • 7
  • 19
1

Another base R solution is to use ifelse as below:

z <- within(z,total <- quantity*ifelse(location=="china",1,3))

such that

> z
  location quantity total
1    china      100   100
2    china      200   200
3       US      100   300
4       US      200   600
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81