Function to find min max solution


#1

Hello,
For this question I’m using the iris dataset which is in the R library
This may sound like a relatively simple question but i’m trying to write a function that takes its arguments as iris Species type and an attribute name, and then returns the minimum and maximum values of the attribute for that Species type?
I’m relatively new to R and believe that knowing how to create a function to do this, will allow me to implement it onto other scenarios.
Kind regards
Ronnie


#2

Try the range() function.


#3

I tried doing
minmax<-function(Species, Sepal.Length | Sepal.Width | Petal.Length | Petal.Width)
{re<-range(Species, Sepal.Length | Sepal.Width | Petal.Length | Petal.Width) return(re) }

However I’m receding an error stating
Error: unexpected symbol in
“Minmax<-function(Species, Sepal.Length | Sepal.Width | Petal.Length | Petal.Width)
{re<-range(Species,Species, Sepal.Length | Sepal.Width | Petal.Length | Petal.Width) return”

I’m wondering what I’ve done wrong ?


#4

You cannot use the | symbol with columns.

Start with a basic expression like
range(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length, iris$Petal.Width)
and then build up your function.


#5

Another way to address the issue is by using a dplyr/tidyr approach. If you haven’t installed dplyr or tidier you can do that by typing the following into your console.

install.packages("dplyr")
install.packages("tidyr")

The piece of code which calculates the min and max.

library(dplyr)
library(tidyr)

min_max <- function(df, funs, ...) {
  dots <- quos(...)
  
  df %>%
    select(...) %>%
    summarise_if(is.numeric, funs) %>%
    gather("Var", "Value") %>%
    separate(Var, sep = "_", into = c("value", "stat"))
}

min_max(iris, funs(min, max), Sepal.Length, Sepal.Width, Petal.Length, Petal.Width)

#6

I’m trying to do it without the use of any packages or libraries so I would’ve used that option otherwise


#7

I’ve tried making them changes but no luck, is there anything you could suggest I’m doing wrong?


#8

The error I’m receiving is stating that the range is not meaningful for factors


#9

This will only use the numeric columns.

min_max <- function(data, ...) {
  dots_str <- vapply(eval(substitute(alist(...))), deparse, character(1))
  column_types <- vapply(data, is.numeric, logical(1))
  numeric_cols <- intersect(dots_str, names(column_types)[column_types])
  
  res <- lapply(numeric_cols, function(x) {
    c(min = min(data[, x]),
      max = max(data[, x]))
  })
  
  names(res) <- numeric_cols
  res
}
min_max(iris, Sepal.Length, Sepal.Width, Petal.Length, Petal.Width)

#10

Brilliant, thanks, that has answered my question exactly!


#11

You will have to describe the output you are after because I have misunderstood your original question.


#12

Would you mind labelling the answer as ‘solution’ then?