cbind replaces String with number?
Asked Answered
P

2

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?

Poulterer answered 9/5, 2014 at 14:49 Comment(0)
A
13

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
Aeronautics answered 9/5, 2014 at 14:55 Comment(2)
I wonder, is there any use for cbind.data.frame over data.frame (i guess it's more explicit...)Filial
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.frameFilial
R
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.

Redfish answered 9/5, 2014 at 14:56 Comment(2)
I have a vector x and y where x holds data and y are classes. I want to seperate x into subvectors for each classPoulterer
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".Redfish

© 2022 - 2024 — McMap. All rights reserved.