【发布时间】:2020-10-02 19:49:00
【问题描述】:
我在数据上苦苦挣扎了很长时间,但我不知道如何解决我的问题。我研究营养数据,这些数据可以被这个数据集伪造:
library(tidyverse)
library(lubridate)
# Used for data generation
groupFunction <- function(cat){
case_when(
cat == "apple" ~ "food",
cat == "bread" ~ "food",
cat == "cheese" ~ "food",
cat == "chocolate" ~ "candy",
cat == "water" ~ "drink",
cat == "tea" ~ "drink"
)
}
# Generate the data
set.seed(0)
fakeData <- tibble(
id = c(rep("A", 10), rep("B", 10), rep("C", 10), rep("D", 10)),
eaten_at = sample(seq(as.POSIXct('2020/01/01'), as.POSIXct('2020/01/05'), by="15 min"), 40),
category = sample(rep(c("apple", "bread", "cheese", "chocolate", "water", "tea"), 10), 40),
group = groupFunction(category),
amount = sample(10:100, 40)
)
# For every id, for each day, every hour and each category: sum the eaten amount,
# and keep 0 eaten amount so it is encounted in the mean calculation in step 2!
# PROBLEM: we loose time intervals where a given id didn't eat anything, this will
# biais the mean calculation in step 2!
step1 <- fakeData %>%
mutate(eaten_at_hour = hour(eaten_at)) %>%
group_by(id, eaten_at, eaten_at_hour, category, group) %>%
summarise(eaten_amount = sum(amount)) %>%
ungroup() %>%
complete(nesting(id, eaten_at, eaten_at_hour),
nesting(category, group),
fill = list(eaten_amount = 0))
# For every id, mean over the days the eaten amount for every hour interval.
# As before, keep 0 counts so it's encounted in the mean calculation in step 3!
step2 <- step1 %>%
group_by(id, eaten_at_hour, category, group) %>%
summarise(mean_per_id = mean(eaten_amount)) %>%
ungroup() %>%
complete(nesting(id, eaten_at_hour),
nesting(category, group),
fill = list(mean_per_id = 0))
# Mean over all id
step3 <- step2 %>%
group_by(eaten_at_hour, category, group) %>%
summarise(mean_for_all = mean(mean_per_id)) %>%
ungroup()
# Plot the data
ggplot(step3, aes(x=eaten_at_hour, y=category, color = mean_for_all, shape = group)) +
geom_point( size = 3) +
scale_color_gradient(low="blue", high="red", "Mean eaten\namount [g]")
我要构建的是 x 轴上 1 小时时间间隔和 y 轴上不同食物类别的图,在 24 小时内每个 X 分钟期间所有 id 的平均食用量(即时间间隔必须灵活)。我想要一个看起来像这样的情节:
我的想法是计算:
- 对于每个 ID,
- 这个 id 每天都吃东西,
- 对于每个 X 小时的时间间隔(即使 id 没有吃任何东西),
- 对于每个食品类别:
->合计吃的量
然后:
- 对于每个 id,
- 对于每个类别,
- 在参与期间每 1 小时间隔一次:
->平均食用量
然后:
-> 平均所有 id 以便我们获得每个类别和 24 小时内每 1 小时间隔的平均食用量
为此,我使用了 group_by()、nesting() 和 complete() 函数。但我有 3 个问题:
我希望能够设置所需的时间间隔,可以是 15 分钟,也可以是 2 小时。我还没有找到任何解决方案。
即使他们没有吃任何东西,我也需要为所有 id 设置所有时间间隔(所以 amout = 0),因为当我的意思是几天或 id 之间时,如果我不吃,平均值就会有偏差t 包括零计数。
我的实际数据集包括大约 100k 行,所以我认为我的做法在效率方面不是最合适的。此外,我想为这些数据设计一个闪亮的应用程序,例如,用户可以手动设置时间间隔,这意味着必须一次又一次地计算绘图(当代码效率不高时,计算机的大量工作...... )
我知道我的问题完全针对特定问题,但由于我真的被阻止了,我非常感谢任何关于我的一个或两个问题的帮助/输入/想法。非常感谢!
【问题讨论】:
-
“我使用 group_by()、nesting() 和 complete() 函数。”。你能和我们分享这段代码吗?
-
感谢丹的编辑。我添加了我的代码并试图澄清我的问题。