2

Would you help me to add a different number of columns for row to a dataframe?

For example, I have this DataFrame:

employee <- c('John','Peter','Jolie', 'Katy', 'Pauline')
numberofmonths <- c(7, 5, 11, 3, 12)
employers <- data.frame(employee,numberofmonths)

  employee numberofmonths
1     John              7
2    Peter              5
3    Jolie             11
4     Katy              3
5  Pauline             12

Now, I would like to add to employers as many columns as characters the "employee" names have.

So I would like something like this:

  employee numberofmonths  i  i  i  i  i  i  i
1     John              7 A1 A2 A3 A4 NA NA NA
2    Peter              5 A1 A2 A3 A4 A5 NA NA
3    Jolie             11 A1 A2 A3 A4 A5 NA NA
4     Katy              3 A1 A2 A3 A4 NA NA NA
5  Pauline             12 A1 A2 A3 A4 A5 A6 A7

I have tried this script:

for (i in (1:nrow(employers))) {
  for (j in nchar(as.vector(employers[i,]$employee))){

  employers<-cbind(employers, i=paste("A", i, sep=""))
}}

But instead of giving A1:A4 for John and... A1:A7 for Pauline, it gives A1:A5 for all of them:

  employee numberofmonths  i  i  i  i  i
1     John              7 A1 A2 A3 A4 A5
2    Peter              5 A1 A2 A3 A4 A5
3    Jolie             11 A1 A2 A3 A4 A5
4     Katy              3 A1 A2 A3 A4 A5
5  Pauline             12 A1 A2 A3 A4 A5

Of course, for the names that have less characters than others, we will have some columns with NA. I am working with a big dataframe with a lot of strings so anything manual will work. This is only an example so the Ai values mean nothing.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Celini
  • 23
  • 3
  • You could do something like cbind.fill as described here: http://stackoverflow.com/questions/7962267/cbind-a-df-with-an-empty-df-cbind-fill – Raad Mar 16 '16 at 16:49
  • `cbind(employers, read.table(text = sapply(employee, function(x) paste0('A', sequence(nchar(x)), collapse = ' ')), fill = TRUE))` – rawr Mar 16 '16 at 17:35

4 Answers4

2

Here's a solution using plyr:

require(plyr)
cbind(employers, rbind.fill.matrix(lapply(nchar(employee),  function(z) t(paste0("A", 1:z)))))
Raad
  • 2,675
  • 1
  • 13
  • 26
1

Try this:

nc<-nchar(as.character(employers$employee))
mat<-matrix(NA_character_,nrow=nrow(employers),ncol=max(nc))
indices<-sequence(nc)
values<-paste0("A",indices)
mat[cbind(rep(1:nrow(employers),nc),indices)]<-values
cbind(employers,mat) 
#  employee numberofmonths  1  2  3  4    5    6    7
#1     John              7 A1 A2 A3 A4 <NA> <NA> <NA>
#2    Peter              5 A1 A2 A3 A4   A5 <NA> <NA>
#3    Jolie             11 A1 A2 A3 A4   A5 <NA> <NA>
#4     Katy              3 A1 A2 A3 A4 <NA> <NA> <NA>
#5  Pauline             12 A1 A2 A3 A4   A5   A6   A7
nicola
  • 24,005
  • 3
  • 35
  • 56
0
employee <- c('John','Peter','Jolie', 'Katy', 'Pauline')
numberofmonths <- c(7, 5, 11, 3, 12)
employers <- data.frame(employee,numberofmonths)
employers$employee <- as.character(employers$employee)

emp_app <- as.data.frame(matrix(NA,
                                nrow = nrow(employers), 
                                ncol = max(nchar(employers$employee))))
for (i in seq_len(nrow(employers))) {
  nm_lngth <- nchar(employers$employee)[i]
  nm_string <- paste0("A", seq_len(nm_lngth))
  for (j in seq_len(nm_lngth)) {
    emp_app[i, j] <- nm_string[j]
  }
}
employers <- cbind(employers, emp_app)
matthias
  • 164
  • 1
  • 10
0

Probably not the best solution, but it works

employee <- c('John','Peter','Jolie', 'Katy', 'Pauline')
numberofmonths <- c(7, 5, 11, 3, 12)
employers <- data.frame(employee,numberofmonths)
max = max(nchar(as.character(employers[,1])))
for (c in 1:max) {
    employers[,c+2] = ifelse(nchar(as.character(employers[,1]))>=c, paste0("A",c), NA)
}
Xiongbing Jin
  • 11,779
  • 3
  • 47
  • 41