Background
I'm querying a mongodb database to find a document:
library(rmongodb)
...
res <- mongo.find.one(m, n, q, f) # <~~ returns BSON
res <- mongo.bson.to.list(res) # <~~ converts BSON to list
I'm then using this answer to try and convert it to a data frame
df <- as.data.frame(t(sapply(res[[1]], '[', seq(max(sapply(res[[1]],length))))))
However, this gives me a data frame of lists (subsetted here for convenience):
data
> dput(df)
structure(list(horse_id = list(17643L, 4997L, 20047L, 9914L,
17086L, 12462L, 18490L, 17642L, 26545L, 27603L, 14635L, 13811L,
27719L, 31585L, 9644L), start_1400m = list(14.76, 14.3, 14.48,
15.11, 14.65, 14.63, 14.85, 14.54, 14.93, 14.5, 14.78, NULL,
NULL, NULL, NULL), `1400m_1200m` = list(12.96, 12.47, 12.47,
13.02, 12.65, 12.92, 13.11, 12.37, 13, 12.84, 12.79, NULL,
NULL, NULL, NULL)), .Names = c("horse_id", "start_1400m",
"1400m_1200m"), row.names = c(NA, 15L), class = "data.frame")
> head(df)
horse_id start_1400m 1400m_1200m
1 17643 14.76 12.96
2 4997 14.3 12.47
3 20047 14.48 12.47
4 9914 15.11 13.02
5 17086 14.65 12.65
6 12462 14.63 12.92
Issue
I would like to library(reshape2); melt and then plot this data using ggplot2, but as expected I can't melt data.frames with non-atomic columns.
> melt(df, id.vars=c("horse_id"))
Error: Can't melt data.frames with non-atomic 'measure' columns
How can I convert this data to a 'standard' data frame (i.e. not a data frame of lists?), or melt it as is?
Update
I hadn't properly considered the NULLs in the data. Using a combination of a comment in this question - replacing NULL with NA and this answer - Convert List to DF with NULLs I came up with
d <- as.data.frame(do.call("rbind", df))
library(plyr)
d <- rbind.fill(lapply(d, function(f) {
data.frame(Filter(Negate(is.null), f))
}))
names(d) <- sub("X","",names(d)) #<~~ clean the names
d <- melt(d, id.vars=c("horse_id")) #<~~ melt for use in ggplot2
This replaces the NULLs with NAs and allows me to melt the data. However, I'm still not fully au fait with what each step is doing yet, or whether this is the right approach.