Reputation: 557
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?
Upvotes: 6
Views: 31829
Reputation: 263471
That d2 object is being printed as an atomic vector would be. Maybe if you showed us either dput(d2) or str(d2) you would havea better understanding of R lists. Furthermore that first bit of code does not produce a two column dataframe, either.
> d<-data.frame(id=1, numobs=1)[0, ] # 2-cl dataframe with 0 rows
> dput(d)
structure(list(id = numeric(0), numobs = numeric(0)), .Names = c("id",
"numobs"), row.names = integer(0), class = "data.frame")
> d2 <- list(id="fifty three", numobs=6) # names that match names(d)
> rbind(d,d2)
id numobs
2 fifty three 6
Upvotes: 0
Reputation: 18691
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
Upvotes: 6
Reputation: 11
For starters, the routine checker appears to be looking for columns labeled "id" and "nobs". If that doesn't match your file output, you'll get that error.
I'm taking what is probably the same class and had the same error; correcting my column names made that go away (I'd labeled the 2nd one "nob" not "nobs"!) Now I've gotten the routine checker to complete correctly, or so it seems... but it outputs three data files, and the first and last files are correct but the second one yields "Sorry, that is incorrect." No further feedback. Maddening!
No point posting my code here as it runs fine locally with all the course examples, and it's kinda hard to debug when you don't know what the script is asking for. Sigh.
Upvotes: 1