Keep row names when using rbind.fill in R
Asked Answered
L

2

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!

Laufer answered 7/5, 2013 at 14:54 Comment(7)
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.Precedence
@Precedence agreed :) i have just submitted it on github github.com/hadley/plyr/issues/156Normandnormandy
Plyr does not support row names. It's a better idea to put them in a variable, and then deal with them explicitly.Survival
@Survival any reason why plyr functions that operate on data.frames shouldn't support row names? This seems like a natural and trivial change to add to rbind.fill.Precedence
@Precedence 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.Survival
@Survival - 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.Precedence
@Precedence I'd happily accept a patch and test casesSurvival
L
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.

Lindesnes answered 7/5, 2013 at 15:14 Comment(2)
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.Featurelength
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.Featurelength
L
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 )
Laufer answered 2/2, 2018 at 15:32 Comment(2)
Are you sure? smartbind doesn't keep rownames either!Explication
@TMS - huh, it did 2 years ago. I removed the checkLaufer

© 2022 - 2024 — McMap. All rights reserved.