2

I have a data set and I want to extract the restaurant name by rating and state. I want to write a function with two arguments: state and rating.

> rest_data
  restaurant_name rating state  visitors_per_day
1          a      3.4    NY           34
2          b      5.0    CA           20
3          c      4.0    NY           11 
4          d      4.3    AZ           34 
5          e      4.9    NY           14
6          f      3.0    CA           21 

This is how I should call the function: state name and the rating

my_function("NY", 4.9)

I tried various ways but I was only able to extract using 1 argument.

Thank you

LyzandeR
  • 37,047
  • 12
  • 77
  • 87
Zar
  • 47
  • 1
  • 9

1 Answers1

3

Something like this maybe:

get_rest <- function(state, rating) {
  rest_data[rest_data$state == state & rest_data$rating == rating, 'restaurant_name']
}

get_rest('NY', 4.9)
#[1] e

And actually this is a much better way to test it:

#almost equal is a vectorised form of all.equal that
#checks if two numbers are equal but with a tolerance level
#because of the inconistenies of storing numbers in a computer
#check: http://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal
#for details
almost.equal <- function (x, y, tolerance=.Machine$double.eps^0.5,
                          na.value=TRUE)
{
  answer <- rep(na.value, length(x))
  test <- !is.na(x)
  answer[test] <- abs(x[test] - y) < tolerance
  answer
} 

get_rest <- function(state, rating) {
  rest_data[rest_data$state == state & almost.equal(rest_data$rating, rating),
            'restaurant_name']
}

get_rest('NY', 4.9)
#[1] e

I have stolen almost.equal from here

LyzandeR
  • 37,047
  • 12
  • 77
  • 87
  • It might even make sense to store the rating as character or factor data, if there is only 1 decimal point of specificity. This would avoid the need for mucking about with numerical accuracy tolerances. – thelatemail Nov 26 '15 at 00:30
  • Yeah this is very true. I was actually thinking to post this as my initial answer but then I decided it might be better to go with `almost.equal` (as a generic option). Very valid comment, thanks @thelatemail – LyzandeR Nov 26 '15 at 00:34
  • Or for that matter store it as integers from 0 to 50 and make sure that all comparisons are integer-to-integer. – thelatemail Nov 26 '15 at 00:38
  • That's another good one @thelatemail and it would work for sure, thanks. I ll write it down tomorrow, I can barely keep my eyes open atm. 1am in the UK :P – LyzandeR Nov 26 '15 at 00:45
  • @LyzandeR Thank you for explaining in the comments so thoroughly, It does make sense. I did not know about this function. Learned smth new. :) – Zar Nov 26 '15 at 07:01
  • Great. Happy to have helped @Zar . You are welcome :) – LyzandeR Nov 26 '15 at 09:37