Krutik
Krutik

Reputation: 501

How to set an R function where a parameter does not have to be present

I have a function where and I would like to make it's parameters optional in case the data is unavailable.

I have shown a toy example here, but the principle is the same.

Here is the toy data.

X <- data.frame(row.names = c("Paladin", "Wizard", "Rouge"), 
                 "Score" = c(5, 4, 5))


Y <- data.frame("Class" = c("Wizard", "Barbarian", "Warlock"),
                "Race" = c("Human", "Drow", "Half-orc"))


Z <- data.frame("Class" = c("Paladin", "Wizard", "Druid"),
                "Race" = c("Human", "Human", "Half-elf"))

Here is the function.

library(tidyverse)

MatrixMaker <- function(X, Y, Z){
  df1 <- X %>% mutate(GAME1 = as.integer(rownames(X) %in% Y[[1]]))
  
  rownames(df1) <- rownames(X)
  
  df2 <- df1 %>% mutate(GAME2 = as.integer(rownames(df1) %in% Z[[1]]))
  
  return(df2)
}

> MatrixMaker(X = X, Y = Y, Z = Z)

  Level GAME1 GAME2
1     5     0     1
2     4     1     1
3     5     0     0

I would like it so that Y and Z can not be present in the function, and the function still works. Instead of Y or Z, the function would add a new column of 0's.

I attempted the function below but either am not using the if, else functions correctly or this is not an appropriate method.

MatrixMaker2 <- function(X, Y= NULL, Z = NULL){
  
  if(Y = NULL){
    
    df1$GAME1 <-0
    
  } else {
    
  df1 <- X %>% mutate(GAME1 = as.integer(rownames(X) %in% Y[[1]]))}
  
  rownames(df1) <- rownames(X)
  
  if(Z = NULL){
    
    df2$GAME2 <- 0
    
  } else {df2 <- df1 %>% mutate(GAME2 = as.integer(rownames(df1) %in% Z[[1]]))}
  
  return(df2)
}

Any help would be most appreciated.

Upvotes: 1

Views: 129

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 173803

I think this could be simplified by doing it in base R and using missing to test for missing arguments:

MatrixMaker <- function(X, Y, Z)
{
  X$GAME2 <- X$GAME1 <- numeric(nrow(X))
  if(!missing(Y)) X$GAME1 <- as.integer(rownames(X) %in% Y[[1]])
  if(!missing(Z)) X$GAME2 <- as.integer(rownames(X) %in% Z[[1]])
  X
}

This behaves as follows:

MatrixMaker(X, Y, Z)
#>         Score GAME1 GAME2
#> Paladin     5     0     1
#> Wizard      4     1     1
#> Rouge       5     0     0

MatrixMaker(X, Y)
#>         Score GAME1 GAME2
#> Paladin     5     0     0
#> Wizard      4     1     0
#> Rouge       5     0     0

MatrixMaker(X)
#>         Score GAME1 GAME2
#> Paladin     5     0     0
#> Wizard      4     0     0
#> Rouge       5     0     0

MatrixMaker(X, Z = Z)
#>         Score GAME1 GAME2
#> Paladin     5     0     1
#> Wizard      4     0     1
#> Rouge       5     0     0

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

Upvotes: 3

Related Questions