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.

2
  • You could do something like cbind.fill as described here: stackoverflow.com/questions/7962267/… Commented Mar 16, 2016 at 16:49
  • cbind(employers, read.table(text = sapply(employee, function(x) paste0('A', sequence(nchar(x)), collapse = ' ')), fill = TRUE)) Commented Mar 16, 2016 at 17:35

4 Answers 4

2

Here's a solution using plyr:

require(plyr)
cbind(employers, rbind.fill.matrix(lapply(nchar(employee),  function(z) t(paste0("A", 1:z)))))
Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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)
}

Comments

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.