2
votes

I have 10 (for example) dataframes with similar names like df1,df2,df3,... with 10 columns I'd like to give names for 10th column in each dataframe like dataframe name(10th column in df1 must has "df1" name, in df2 -- "df2" and etc)

i tried this

for (i in paste0("df",1:10)){
     assign(names(get(i))[10],
            value=i
            )
     }

but nothing changed How can i solve this problem?

4
Put all your dataframes in a named list, then iterate over the names?Heroka

4 Answers

6
votes

You can make it in three steps :

--get

--change colnames

-- assign

for (i in paste0("df",1:3)){
  d=get(i)
  colnames(d)[10]=i
  assign(i,d)
}
4
votes

If your command is given in a string, then you can implement it by eval(parse(text = command)).

For example, this is possible:

eval(parse(text = 'names(df1) <- "colname"'))

Preparing a set of commands for each data.frame is not that hard. I think in your case,

commands <- sprintf('names(df%d)[10] <- "df%d"', 1:10, 1:10)

Then,

eval(parse(text = commands))
1
votes

We can use Map. Get the datasets in a list with mget ('lst'), use Map to change the 10th column name to the corresponding name of the list ('lst1'). It is better to keep the datasets in the list, but if we need to modify the original dataset object, use list2env.

 lst <- mget(paste0('df', 1:10))
 lst1 <- Map(function(x,y) {names(x)[10] <- y; x},  lst, names(lst))
 list2env(lst1, envir=.GlobalEnv)
1
votes

The documentation for assign says:

x a variable name, given as a character string.

You try to use it with something else than a variable name, which seems not to be working.

I have simplified your problem to three data frames with three columns, just to make creating the sample data easier. So these are the data frames:

df1 <- data.frame(a = 1:10, b = 1:10, c = 1:10)
df2 <- df1
df3 <- df1

And this is the loop that changes the names of the third columns:

for (i in paste0("df",1:3)){
   call <- bquote(names(.(as.name(i)))[3] <- i)
   eval(call)
}

What I do here first is create the call (you can look at call to see that it contains the line of code that you actually want to evaluate). as.name(i) converts the character i into a variable name, and .() tells bquote to replace known symbols inside the brackets by their value. The known symbol inside is i which will be replaced by "df1" and the character string is then converted to a symbol.

Once the call is constructed, it is evaluated with eval().