I have created an empty data frame in R with two columns:
d<-data.frame(id=c(), numobs=c())
I would like to append this data frame (in a loop) with a list, d1
that has output:
[1] 1 100
I tried using rbind
:
d<-rbind(d, d2)
and merge
:
d<-merge(d, d2)
And I even tried just making a list of lists and then converting it to a data frame, and then giving that data frame names:
d<-rbind(dlist1, dlist2)
dframe<-data.frame(d)
names(dframe)<-c("id","numobs")
But none of these seem to meet the standards of a routine checker (this is for a class), which gives the error:
Error: all(names(cc) %in% c("id", "nobs")) is not TRUE
Even though it works fine in my workspace.
This is frustrating since the error does not reveal where the error is occurring.
Can anyone help me to either merge 2 data frames or append a data frame with a list?
I think you are confusing the purpose of rbind
and merge
. rbind
appends data.frames or named lists, or both vertically. While merge
combines data.frames horizontally.
You seem to be also confused by vector
's and list
's. In R, list
can take different datatypes for each element, while vector
has to have all elements the same type. Both list
and vector
are one-dimensional. When you use rbind
you want to append a named list
, not a named/unnamed vector
.
The way you define a vector
is with the c()
function. The way you define an unnamed list is with the list()
function, like so:
vec1 = c(1, 10)
# > vec1
# [1] 1 10
list1 = list(1, 10)
# > list1
# [[1]]
# [1] 1
#
# [[2]]
# [1] 10
Notice that both vec1
and list1
have two elements, but list1
is storing the two numbers as two separate vectors (element [[1]]
the vector c(1)
and [[2]]
the vector c(10)
)
You can also create named vectors and lists. You do this by:
vec2 = c(id = 1, numobs = 10)
# > vec2
# id numobs
# 1 10
list2 = list(id = 1, numobs = 10)
# > list2
# $id
# [1] 1
#
# $numobs
# [1] 10
Same data structure for both, but the elements are named.
Notice that list2
has a $
in front of each element name. This might give you some clue that data.frame
's are actually list
's with each column an element of the list
, since df$column
is often used to extract a column from a dataframe. This makes sense since both list
's and data.frame
's can take different datatypes, unlike vectors
's.
rbind
functionWhen your first element is a dataframe, rbind
requires that what you are appending has the same names as the columns of the dataframe. Now, a named vector
would not work, because the elements of a vector
are not treated as columns of a dataframe, whereas a named list
matches elements with columns if the names are the same:
To demonstrate:
d<-data.frame(id=c(), numobs=c())
rbind(d, c(1, 10))
# X1 X10
# 1 1 10
rbind(d, c(id = 1, numobs = 10))
# X1 X10
# 1 1 10
rbind(d, list(1, 10))
# X1 X10
# 1 1 10
rbind(d, list(id = 1, numobs = 10))
# id numobs
# 1 1 10
Knowing the above, it is obvious that you can most certainly also rbind
two dataframes with column names that match:
df2 = data.frame(id = 1, numobs = 10)
rbind(d, df2)
# id numobs
# 1 1 10