eterpage
eterpage

Reputation: 3

How do I automate adding new columns to dataframe? (R)

I'm trying to make a script in Rstudio where I input some columns, then it outputs a new column for each column input. The problem is, I don't know how many columns will be input; this number will change. I'm trying to loop through to create the columns, but each command I know requires a name for the column and this is giving me trouble. I can create random names for the new columns, but I can't make the loop target the column names. Without names, I can't make any columns. I can put the names in nametable, but add_column doesn't seem to be able to target it for some reason.

If anyone can figure out how to add columns without names, or how to add them with names from this kind of function, I would really appreciate it.

colcount <- ncol(tdata)

nametable <- NULL

for (i in 2:(colcount)){
nametable[i] <- paste("v",i)
}

for (i in 2:(colcount)) {
idk4<- nametable[i]
  tdata <- add_column(tdata,idk4,.after = colcount)
}

Corrected code:

rowcount <- nrow(tdata)
colcount <- ncol(tdata)

for (i in 2:ncol(tdata)){
  to_add <- data.frame(name1 = 1:1248)  
for (c in seq_len(ncol(to_add))) {
  tdata[[paste0('v_',i-1)]] <- to_add[,c]
}}

Upvotes: 0

Views: 819

Answers (2)

astrofunkswag
astrofunkswag

Reputation: 2688

If you debug your loop, you'll see that add_column is trying to add a column named idk4 for each iteration, and it breaks because of the duplicate column name. If you want to add the column name that's inside nametable, you use !!. Check out this link for more:

tdata = data.frame()

for (i in 2:(colcount)) {
  idk4<- nametable[i]
  tdata <- add_column(tdata,!!(nametable[i]),.after = colcount)
}

This will be a zero row dataframe. To add values you need the := operator like the link shows. Also not sure why you count from 2, leaving an NA in position 1 but that's up to you.

Upvotes: 0

ClancyStats
ClancyStats

Reputation: 1231

Data frames are essentially just lists under the hood so you can directly assign a column as long as you can come up with a suitable name for it.

df <- data.frame(name1 = rnorm(10), name2 = rnorm(10))
to_add <- data.frame(name1 = rnorm(10), name2 = rnorm(10))

for(i in seq_len(ncol(to_add))) {
  df[[paste0('v_', i)]] <- to_add[,i]
}

df
#>         name1      name2         v_1        v_2
#> 1   0.1664923 -0.0993323  0.00960158  0.1065084
#> 2   0.4416025  1.4305505  1.31583098 -0.7034243
#> 3  -0.2824676 -1.6445144  0.06301939 -0.6026345
#> 4   0.3295798  0.2456593  2.14454251  0.1950088
#> 5  -0.2226529  0.6365769  0.02249166 -1.4926480
#> 6   0.1480690 -0.9051266  0.20976601 -0.5762838
#> 7  -1.1215822 -0.6685792  0.29167861 -0.5923874
#> 8   0.8513272 -0.6316098 -1.04509640 -1.9839998
#> 9  -0.1280242  0.3425758  1.53816824  1.8885009
#> 10 -0.1315104 -0.9829902 -0.96036102 -1.3502144

Created on 2019-09-18 by the reprex package (v0.3.0)

Upvotes: 2

Related Questions