'Functions and loops, am I missing something?

I'm new to R and I feel like I may not be understanding how functions work.
I have a few tibbles which I have transposed using t() and now want to

  • Use row 1 to assign column names
  • drop row 1 from the table.
colnames(df) <- x[1, ]
df <- x[-1, ]

Works nicely for what I need it for, however I have about 12 different tables I thought a function would be slightly easier.

name_re <- function(x) {
  colnames(x) <- x[1, ]
  x <- x[-1, ]
}

I can't see why this wouldn't work.

Ideally it would have liked to make a list of all my tibbles and loop through them, but I've been told to avoid using them in R. I originally thought

df_list <- list(df1, df2, df3, df4, df5, df6, df7, df8) 

for (i in df_list) {
  name_re(i)
}

However this doesn't work either. I feel like I'm fundamentally not getting something about R. I have some experience with bash and python but I have no idea what I am missing ?


For some reason I'm still unable to get this to work, I am assuming I've done something wrong somewhere along the line but can't work out where.

pacman::p_load(tidyverse)

df <- read_tsv("gmvar_comp_full_neg_1ul_20220221_cut.csv")  
df1 <- df%>% select(CompoundsID,`ReplicateGroupedArea:01a`:`ReplicateGroupedArea:03c`)%>% t()

name_re <- function(x){
  colnames(x) <- x[1,]
  x <- x[-1,]
  return(x)
}
name_re(df1)

I still have the same unedited data after running all the commands

r


Solution 1:[1]

You're pretty close.

Your function is pretty much correct, but unfortunately it is returning its value invisibly, because you end with an assignment. This is a bit of subtlety, I don't think it means you have a fundamental misunderstanding.

Your version does work, but invisible returning is a bit confusing:

# this runs but the console shows no output
name_re(mtcars)
# this does show the output
print(name_re(mtcars))
# assignments also work
xx <- name_re(mtcars)
xx

Instead, don't end your function with an assignment. Use e.g. simply:

name_re <- function(x){
  colnames(x) <- x[1,]
  x[-1,]
}

Or return explicitly:

name_re <- function(x){
  colnames(x) <- x[1,]
  x <- x[-1,]
  return(x)
}

To apply a function to a list, you can use lapply:

df_list <- list(mtcars, mtcars)
lapply(df_list, name_re)

(Just to note, the problem you are trying to solve usually is better fixed by reading in your data correctly. If your first row has the data headers, it means your columns may all have been coerced to character vectors. Use the options of the function you are using to read in the data with the correct headers in place.)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1