5
x = iris$Sepal.Width;
y = iris$Species;

m = cbind(x,y);

the output of m is:

        x  y
  [1,] 3.5 1
  [2,] 3.0 1
  [3,] 3.2 1
  [4,] 3.1 1
  [5,] 3.6 1
  [6,] 3.9 1

but I want 'setosa', etc in column y instead of a number

how can I do that?

I want to combine the 2 Vectors because I want to filter afterwards with

m[m[,"y"]=="virginica",]

or is ther another oportunity to do that without cbind?

user2071938
  • 2,055
  • 6
  • 28
  • 60

2 Answers2

12

For vectors being combined with cbind, the result would be a matrix, which can only hold one type of data. Thus, the "Species" factor gets coerced to its underlying numeric value.

Try cbind.data.frame instead (or just data.frame) if you need your columns to have different data types.

> head(data.frame(x, y))
    x      y
1 3.5 setosa
2 3.0 setosa
3 3.2 setosa
4 3.1 setosa
5 3.6 setosa
6 3.9 setosa
> head(cbind.data.frame(x, y))
    x      y
1 3.5 setosa
2 3.0 setosa
3 3.2 setosa
4 3.1 setosa
5 3.6 setosa
6 3.9 setosa
A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
  • I wonder, is there any use for `cbind.data.frame` over `data.frame` (i guess it's more explicit...) – MichaelChirico Sep 01 '17 at 15:52
  • 1
    just glanced at the `cbind.data.frame` code, and indeed it is basically just a wrapper for `data.frame`, with the addition of the `deparse.level` argument, see `?cbind.data.frame` – MichaelChirico Sep 01 '17 at 15:54
1

cbind() returns a matrix which has to be of a single class. In this case everything is converted to character because that is the most general class (you can express numbers as characters but not the other way around). R relies on data.frame to store columns of different classes.

To do what you want you can either explicitly create a new data.frame or use a subset of the current one:

iris2 <- data.frame(x=iris$Sepal.Width, y=iris$Species)  ## creates new data.frame
iris[, c("Sepal.Width", "Species")   ## returns subset of iris

If you post the problem you are trying to solve there may be a more streamlined way to do the filtering you want.

ilir
  • 3,236
  • 15
  • 23
  • I have a vector x and y where x holds data and y are classes. I want to seperate x into subvectors for each class – user2071938 May 09 '14 at 15:02
  • Take a look at `split()` to generate a list of `data.frame` objects, or functions like `tapply()` to apply a function to each subset. There are more efficient methods too, but these should get you on your way. Google "split-apply-combine with R". – ilir May 09 '14 at 15:07