Flay Auchter
Flay Auchter

Reputation: 145

Converting rows/strings into a single column in R

If I have the following object

[1] 0 1 0 0 0 0 0 0 0

How do I convert it to this so that I can put it in one column and it aligns with my other columns in my data frame:

0
1
0
0
0
0
0

I thought list might work...but which function should this work on

So sorry for asking a suppose to be basic question...

Upvotes: 0

Views: 2059

Answers (2)

Ricardo Saporta
Ricardo Saporta

Reputation: 55360

In addition to Aruns great and detailed answer, there are two things worth noting:

First, R recycles shorter items to match the length of the longer items. In the case of adding a vector to a data.frame, this will only occur if the number of rows of the data.frame is an exact multiple of the length of the vector.

 zshort <- c(1, 2, 3)

# will be `0` if exact multiple:
length(zshort)  %/% nrow(DF)
# [1] 0

cbind(DF, zshort)
#  cbind(DF, zshort)
#  x y zshort
#  1 a      1
#  2 b      2
#  3 c      3
#  4 d      1   <~~ Recycling
#  5 e      2
#  6 f      3
#  7 g      1   <~~ Recycling
#  8 h      2
#  9 i      3

(2) You can also add a new column to a data.frame using "[" as follows:

# name of the column does NOT have to be
#  the same as the name of the vector
DF[, "newName"] <- z

DF[, "shortz"]  <- zshort

# You can also delete existing columns
DF[, "y"]  <- NULL

DF
#   x newName shortz
#   1       1      1
#   2       2      2
#   3       3      3
#   4       1      1
#   5       2      2
#   6       3      3
#   7       1      1
#   8       2      2
#   9       3      3

Upvotes: 2

Arun
Arun

Reputation: 118799

If you have a data.frame say, "DF", like this:

DF <- data.frame(x=1:9, y=letters[1:9])

And you've a vector z:

z <- c(0, 1, 0, 0, 0, 0, 0, 0, 0)

Note that the number of rows in your data.frame and the length of the vector has to be the same if you want to add the vector to a data.frame as a new column.

dim(DF) # dimensions of data.frame
# [1] 9 2

length(z) # length of vector
# [1] 9

Now, you can use cbind to get the new column as follows:

cbind(DF, z)
#   x y z
# 1 1 a 0
# 2 2 b 1
# 3 3 c 0
# 4 4 d 0
# 5 5 e 0
# 6 6 f 0
# 7 7 g 0
# 8 8 h 0
# 9 9 i 0

If you have a vector whose length is not equal to that of the data.frame rows, then,

z <- c(0, 1, 0, 0, 0, 0, 0) # length is 7

cbind(DF, z)
# Error in data.frame(..., check.names = FALSE) : 
#   arguments imply differing number of rows: 9, 7

cbind'ing results in error due to unequal lengths. In this case, I could think of a couple ways to store this as a list.

First, you can keep your data.frame DF as such and create a list with its first element as the data.frame and the second as a vector as follows:

my_l <- list(d1 = DF, d2 = z)

# $d1
#   x y
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d
# 5 5 e
# 6 6 f
# 7 7 g
# 8 8 h
# 9 9 i
# 
# $d2
# [1] 0 1 0 0 0 0 0

Alternatively, you can convert your data.frame to a list (a data.frame is internally a list) and create a list whose elements are all vectors as follows:

my_l <- c(as.list(DF), list(z=z))

# $x
# [1] 1 2 3 4 5 6 7 8 9
# 
# $y
# [1] a b c d e f g h i
# Levels: a b c d e f g h i
# 
# $z
# [1] 0 1 0 0 0 0 0

Note that as.list coerces a data.frame columns to a list with it's names the column names of the data.frame. We then create a new list z and then concatenate using the c operator.

Hope this betters your understanding a bit.

Upvotes: 2

Related Questions