MGJ-123
MGJ-123

Reputation: 634

How to improve this function to accept multiple arguments

I have a function which alters the name of the column based on its index. It is limited to only 2 columns. It'd be good to change this function to accept multiple inputs. However I am unsure what data structures I'd need to use how to do this. Can anyone point me in the right direction?

Here is a sample dataset and the function:

id <- c(500,600,700,800)
test1 <- c(1,4,5,6)
test2 <- c(6,4,3,6)
test3 <- c(4,3,4,6)
test4 <- c(3,5,6,6)
test <- data.frame(id,test1,test2,test3,test4)

func1 <- function (df, col_name1, col_range1, col_name2, col_range2) {
  for (i in 1:length(names(df))) {
    if (i %in% col_range1) {
      names(df)[i] <- paste(col_name1,names(df)[i], sep = "_")
    }
    else if (i %in% col_range2) {
      names(df)[i] <- paste(col_name2,names(df)[i], sep = "_")
    }
  }
  return(df)
}

This function can be used like so:

test <- func1(test, "MH", 2:3, "MP", 4:5)

It'd be good to change the function so that it could accept an input like so:

test <- func1(test, "MH", 2, "ML", 3, "MP", 4:5)

Any ideas on this?

Upvotes: 1

Views: 48

Answers (2)

Wil
Wil

Reputation: 3188

You could also take a named list as your second argument where the name of the list element is the column prefix to add and the value of the list element is a numeric vector of the column indices.

func1 <- function (df, col_names) {
  for (n in seq_along(col_names)) {
    name <- names(col_names)[n]
    cols <- col_names[n]

    for (i in cols) {
      colnames(df)[i] <- paste(name,colnames(df)[i], sep = "_")
    }

  }

  return(df)
}

> func1(test, col_names = list(MH = 2, ML = 3, MP = 4:5))
   id MH_test1 ML_test2 MP_test3 MP_test4
1 500        1        6        4        3
2 600        4        4        3        5
3 700        5        3        4        6
4 800        6        6        6        6


Upvotes: 2

Roland
Roland

Reputation: 132746

I don't like the proposed design. I would use exactly one parameters for the prefixes and one parameter for the indices, i.e., two lists:

func1 <- function (df, col_names, col_ranges) {
  mapply(function(n, i) names(df)[i] <<- paste(n, names(df)[i], sep = "_"), 
         col_names, col_ranges)
  return(df)
}

func1(test, list("MH", "ML", "MP"), list(2, 3, 4:5))
#   id MH_test1 ML_test2 MP_test3 MP_test4
#1 500        1        6        4        3
#2 600        4        4        3        5
#3 700        5        3        4        6
#4 800        6        6        6        6

Upvotes: 2

Related Questions