6

Does anyone know how to keep rownames in the rbind.fill function.

library(plyr)

#creating data
a <- mtcars[ 1:5 , c("mpg","hp","gear") ]
b <- mtcars[ 6:10 , c("mpg","disp","gear") ]

#does not work because there are different colnames
rbind(a,b)

#works but eliminates the rownames
bound <- rbind.fill( a , b )

I am setting up a loop where objects will be connected using rbind.fill. Right now I am using the combine function like this:

namess <- c( rownames(a) , rownames(b) )
rownames(bound) <- namess

I thought that there might be a better way. Thanks!

MatthewR
  • 2,660
  • 5
  • 26
  • 37
  • I would consider this a bug. I don't know if `plyr` has a bug report forum/place, but if it does someone should link to it and this should be submitted imo. – eddi May 07 '13 at 15:19
  • 1
    @eddi agreed :) i have just submitted it on github https://github.com/hadley/plyr/issues/156 – Anthony Damico May 07 '13 at 15:21
  • 2
    Plyr does not support row names. It's a better idea to put them in a variable, and then deal with them explicitly. – hadley May 07 '13 at 15:29
  • @hadley any reason why `plyr` functions that operate on `data.frame`s shouldn't support row names? This seems like a natural and trivial change to add to `rbind.fill`. – eddi May 07 '13 at 15:50
  • @eddi My reasoning is above: rownames don't add anything you can't already do. Plus it's not obvious how they work with (e.g.) `ddply`. – hadley May 07 '13 at 18:13
  • @hadley - I agree that the issue doesn't apply to `ddply`, but it does to `rbind.fill`. Just because *other* functions in `plyr` don't/can't deal with `data.frame` row names, doesn't mean this one shouldn't either. – eddi May 07 '13 at 18:18
  • @eddi I'd happily accept a patch and test cases – hadley May 07 '13 at 23:22

2 Answers2

2

You could try to apply a custom function that performs rbind.fill and sets initial rownames automatically like that:

# List of sample data
ab.list <- list(a <- mtcars[1:5 , c("mpg","hp","gear")], 
                b <- mtcars[6:10 , c("mpg","disp","gear")])

# Apply custom function (rbind and rownames adjustment) to sample data
do.call(function(...) {

  tmp <- plyr::rbind.fill(...)
  rownames(tmp) <- sapply(ab.list, function(i) {
    rownames(i)
  })

  return(tmp)

}, ab.list)

                   mpg  hp gear  disp
Mazda RX4         21.0 110    4    NA
Mazda RX4 Wag     21.0 110    4    NA
Datsun 710        22.8  93    4    NA
Hornet 4 Drive    21.4 110    3    NA
Hornet Sportabout 18.7 175    3    NA
Valiant           18.1  NA    3 225.0
Duster 360        14.3  NA    3 360.0
Merc 240D         24.4  NA    4 146.7
Merc 230          22.8  NA    4 140.8
Merc 280          19.2  NA    4 167.6

Check out this previous post that deals with a similar problem.

Community
  • 1
  • 1
fdetsch
  • 5,239
  • 3
  • 30
  • 58
  • 1
    It's probably better to extract the row names first from within the function by parsing the arguments in `...` than reaching back into the parent frame for them. – joran May 07 '13 at 15:18
  • I'm actually having trouble coming up with an elegant way of having it handle both passing `ab.list` _and_ `ab.list[[1]], ab.list[[2]]` separately. – joran May 07 '13 at 15:35
1

Since I posted this question five years ago - a new function became available. smartbind solves this issue.

library( gtools) 

#creating data
a <- mtcars[ 1:5 , c("mpg","hp","gear") ]
b <- mtcars[ 6:10 , c("mpg","disp","gear") ]

smartbind( a , b )
MatthewR
  • 2,660
  • 5
  • 26
  • 37