Reputation: 634
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
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
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