1

I'm having trouble When using cbind. Prior to using cbind the object is a data.frame of two character vectors.

After I add a column using cbind, the data.frame object changes class to matrix. I've tried as.vector, declaring h as an empty character vector, etc. but couldn't fix it. Thank you for any suggestions and help.

output <- data.frame(h = character(), st = character()) ## empty dataframe
st <- state.abb 
h <- (rep("a", 50))
output <- cbind(output$h, h) ## output changes to matrix class here
output <- cbind(output, st) ## adding a second column
Ken
  • 11
  • 3
  • 1
    `?cbind` says *The data frame method will be used if at least one argument is a data frame and the rest are vectors or matrices*. You pass two vectors to `cbind` hence why the result is not a dataframe – user20650 May 01 '15 at 21:42
  • Thanks. That's why I created the empty data.frame first, thinking that would keep it a data frame while I keep adding other columns to it. – Ken May 01 '15 at 22:18
  • `output` is a data frame. `output$h` is _not_ a data frame. Hence `cbind(output$h, h)` doesn't invoke any data frame-specific magic. – Hong Ooi May 01 '15 at 23:10

2 Answers2

0

I guess you may not need cbind().

output <- data.frame(state = state.abb, h = rep("a", 50))
head(output)
state h
1    AL a
2    AK a
3    AZ a
4    AR a
5    CA a
6    CO a

@ Ken I'm not sure what you actually want to obtain but it may be easier if variables are kept in a list. Below is an example.

state <- state.abb
h <- rep("a", 50)

lst <- list(state = state, h = h)
mat <- as.matrix(do.call(cbind, lst))
head(mat)
state h  
[1,] "AL"  "a"
[2,] "AK"  "a"
[3,] "AZ"  "a"
[4,] "AR"  "a"
[5,] "CA"  "a"
[6,] "CO"  "a"

df <- as.data.frame(do.call(cbind, lst))
head(df)
state h
1    AL a
2    AK a
3    AZ a
4    AR a
5    CA a
6    CO a
Jaehyeon Kim
  • 1,328
  • 11
  • 16
  • Thanks...though I plan to add more columns. Which makes the converting to matrix a hassle. – Ken May 01 '15 at 22:16
  • Which would you want to obtain: data frame or matrix? – Jaehyeon Kim May 01 '15 at 22:24
  • I would want to obtain a data.frame after all the cbinds. I guess I need to convert from matrix to data.frame after the cbinds are done? Thanks! – Ken May 01 '15 at 22:42
  • If you've got multiple variables to bind, use `do.call()` after creating a list of those variables. I hope the second example of my edited code is useful. – Jaehyeon Kim May 01 '15 at 22:45
  • 1
    This is ending up a bit of a convoluted mess in building a dataframe. Ken can you add details of what you are trying to do, rather than how. Generally, starting from `data.frame(h = character(), st = character())` is not a good way to start. Jaehyeon, first answer is better, and then you can use `cbind`, but some clarification would be good. – user20650 May 01 '15 at 22:54
  • Yes, thank you. I am making a function to with arguments state, pollutant, and rank. To find the states that matches rank for that pollutant. There are three pollutants. My approach was to calculate the ranking of the pollutants in each state and then find the match when the function was called. Hence. I was using cbind to add the columns of ranked pollutants by state. – Ken May 03 '15 at 19:23
  • By the way, I really appreciate the guidance in improving my approach to the problem. – Ken May 03 '15 at 19:24
0

As a complement of info, notice that you could use single bracket notation to make it work with something close to your original code:

data

output <- data.frame(h = letters[1:5],st = letters[6:10])
h2 <- (rep("a", 5))

This won't work

cbind(output$h, h2)
#          h2  
# [1,] "1" "a"
# [2,] "2" "a"
# [3,] "3" "a"
# [4,] "4" "a"
# [5,] "5" "a"
class(cbind(output$h, h2)) # matrix

It's a matrix and factors have been coerced in numbers

this will work

cbind(output["h"], h2)
#   h h2
# 1 a  a
# 2 b  a
# 3 c  a
# 4 d  a
# 5 e  a
class(cbind(output["h"], h2)) # data.frame

Note that with double brackets (output[["h"]]) you'll have the same inadequate result as when using the dollar notation.

moodymudskipper
  • 46,417
  • 11
  • 121
  • 167