1

I want to generate dynamic columns in for loop and assign values to it. Following is my code

   new_df = data.frame()
   for(j in 1:3) {
      new_df[,paste0("code_",j,sep="")] = somevalue
      new_df[,paste0("target_",j,sep="")] = somevalue
   }

When i run above code it gives me an error. How can I generate above columns dynamically ?

   new_df = list()
   for(i in 1:4){
      for(j in 1:3){
          new_df[[paste0("code_",j,sep="")]] =i
         }
     }
    new_df = as.data.frame(new_df)

It only gives me 1 row and 3 columns instead it should return 4 rows and 3 columns

Neil
  • 7,937
  • 22
  • 87
  • 145

4 Answers4

2

How about this?

xy <- vector("list", 3)

for (j in 1:3) {
  x <- data.frame(j, j)
  names(x) <- c(paste0("code_",j,sep=""), paste0("target_",j,sep=""))
  xy[[j]] <- x
}

do.call(cbind, xy)

  code_1 target_1 code_2 target_2 code_3 target_3
1      1        1      2        2      3        3
Roman Luštrik
  • 69,533
  • 24
  • 154
  • 197
2

When you create the data.frame with

new_df = data.frame()

it contains no columns and no rows.

If you now try to add a column by e.g. a vector of values, it complains about data having more elements than rows in your data.frame:

d[,'foo'] <- 'bar'

returning

Error in `[<-.data.frame`(`*tmp*`, , "foo", value = "bar") : 
  replacement has 1 row, data has 0

You can, for example, create a list, and then convert to a data.frame:

new_list <- list()
for(j in 1:3) {
      new_list[[paste0("code_",j,sep="")]] = 1L
      new_list[[paste0("target_",j,sep="")]] = 1L
   }
as.data.frame(new_list)

which returns

  code_1 target_1 code_2 target_2 code_3 target_3
1      1        1      1        1      1        1
setempler
  • 1,681
  • 12
  • 20
1
library(data.table)

new_df <- 0 
new_df <- as.data.table(new_df)
for(j in 1:3) {
  # j<-1
  new_df[,paste0("code_",j):=1]
  new_df[,paste0("target_",j):=2] 
}

you need to initialize the data table, otherwise it is not possible to add a column to it. So if you want your data table to have for instance 10 rows, then just add a vector of 10 zeros for instance and then do the same

quant
  • 4,062
  • 5
  • 29
  • 70
0

I think that you can use a combination of the get/assign functions and mutate to do such operations.

library(plyr)
df1<-data.frame(a=1:10) 
df2<-data.frame(b=11:20)

vec1<-2:11 #values to be incorporated into df1
vec2<-12:21#values to be incorporated into df2

for(j in 1:2){
assign(paste0("newdf",j),mutate(get(paste0("df",j)),k=get(paste0("vec",j))))
} #assigns df1 combined with vec1, to newdf1.
nadizan
  • 1,323
  • 10
  • 23