фонг - кадр данных списков в кадр данных
Я запрашивая базу данных MongoDB, чтобы найти документ:
library(rmongodb)
...
res <- mongo.find.one(m, n, q, f) # <~~ returns BSON
res <- mongo.bson.to.list(res) # <~~ converts BSON to list
Я тогда с помощью this answer, чтобы попытаться преобразовать его в кадре данных
df <- as.data.frame(t(sapply(res[[1]], '[', seq(max(sapply(res[[1]],length))))))
Однако, это дает мне кадр данных списков (subsetted здесь для удобства):
данные
> 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
Выпуск
Я хотел бы library(reshape2); melt
и затем построить эти данные с помощью ggplot2
, но, как и ожидалось, я 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
Как я могу преобразовать эти данные в «стандартный» кадр данных (т.е. не кадр данных списков?), Или melt
это как?
Update
я не учёл должным образом NULL
с в данных. Используя комбинацию a comment in this question - replacing NULL with NA и this answer - Convert List to DF with NULLs я придумал
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
Это заменяет NULL
с с NA
с и позволяет мне melt
данных. Тем не менее, я все еще не полностью au fait с тем, что делает каждый шаг, или же это правильный подход.
Что такое желаемый результат? Что насчет 'melt (lapply (df, unlist))'? – A5C1D2H2I1M1N2O1R2T1
Определенно не используйте sapply, так как он пытается преобразовать свой вывод в список. Согласно комментарию в вашей ссылке, было бы лучше использовать vapply, но я бы согласился применить и обернуть его с помощью unlist, чтобы убедиться, что вывод не является списком. Возможно, мне понадобится переместить unlist на уровень глубже, если вы все равно получите X списков. –
@AnandaMahto - спасибо за предложение, но этот метод теряет связь между значениями 'horse_id' и' start_1400m', '1400m_1200m' (хотя некоторые являются' NULL'), не так ли? – tospig