我有一个非常大的数据框(大约1GB和100万行),从早上10点到下午4点进行观察。 我想用geom_step绘制一些图,它们在1:00:00-1:00:05pm完全放大,所以我认为为了节省RAM和时间,原始数据的子集会更快。 (而不是绘制所有内容并在之后放大)。不幸的是,绘制一切都不是一个选择。 由于我正在使用geom_step,我需要使用前后值包装我的子集,否则事情不能正确绘制。
这是一个示例数据集,实际上比我的数据小得多,但其原理在于:
set.seed(2)
c1 <- sort( sample(round(runif(10,1,10)*10), 10 , replace = TRUE ) )
c2 <- sample(c("A", "C", "T"), 10, replace = TRUE)
c4 <- round(runif(10)*1000)
d1 <- c(5, 12, c1, 96, 97, 98, 100)
d2 <- c("B", "C", c2, "B", "T", "T", "A")
d3 <- c(300, 400, c4, 200, 300, 300, 100)
dcat2 <- c(sample(1:2, 14, replace = TRUE), 1,1)
mydat <- data.frame(time = d1, category = d2, category2 = dcat2 , inventory = d3)
print(mydat)
# time category category2 inventory
# 1 5 B 2 300
# 2 12 C 1 400
# 3 27 C 1 10
# 4 52 C 1 165
# 5 59 T 2 810
# 6 62 A 2 869
# 7 62 C 2 514
# 8 73 C 1 627
# 9 85 A 2 844
# 10 95 C 2 285
# 11 95 T 1 667
# 12 95 A 1 150
# 13 96 B 2 200
# 14 97 T 2 300
# 15 98 T 1 300
# 16 100 A 1 100
require(ggplot2)
p <- ggplot(data=mydat, aes(x = time, y = inventory, group = category, col = category)) +
geom_step() +
facet_grid(.~category2)
print(p)
q <- ggplot(data=mydat, aes(x = time, y = inventory, group = category, col = category)) +
geom_step() +
facet_grid(.~category2) +
coord_cartesian(xlim = c(80,98))
print(q)
这个情节有效,但由于我的真实数据太大,所以需要永远绘制。
我还希望假设步骤图在时间= 0时从零开始并保持它的最后一个值,直到时间= 100,而不是像p
和{q
中那样消失并出现在任何地方。 {1}}
以下内容更符合我的目标。它给出了一个错误,因此对于类别和类别2的每次交互,我需要用mydat.zoom
数据框包含最近的观察结果(之前),最后一次从mydat.zoom
(之后)观察,1} p>
require(dplyr)
mydat.zoom <- filter(mydat, time >80, time < 98)
r <- ggplot(data=mydat.zoom, aes(x = time, y = inventory, group = category, col = category)) +
geom_step() +
facet_grid(.~category2)
print(r)
给出错误,
因为geom_step
在方面绘图时需要至少2个点,但其中一些已经被子集切断到时间80到98之间。
请建议一种有效的方法,找出每个因素,缩放窗口之前的最后一次观察,以及复制最后一次观察并将缩放窗口包裹在这些中的方法(或不同的解决方案!)
答案 0 :(得分:1)
以下是我用来将过去的观察结果推进到正在检查的时间窗口的方法:
require(data.table)
myDT <- as.data.table(mydat)
preDT <- myDT[ time < 80, .SD[.N] , by = .(category, category2)] # for each category/category2 interaction before time =80, take the last observation
mydat.zoom <- rbind(preDT, myDT[ time >= 80 & time <= 98] ) # gives everything from time = 80 to time =98 and the last observation for each thing that happened before time = 80
答案 1 :(得分:0)
好的,这是一个黑客,但它可以帮助你暂时解决这个问题(即直到有人提供更清洁的解决方案)。
这将创建一个临时变量,其中包含每个因子的出现次数。然后过滤结果以确保至少2个数据点。
mydat.zoom <-
filter(mydat, time >80, time < 98) %>% # Your current filtering
group_by(category2) %>% # Using cat2 for this example
mutate(cat2_cnt = n()) %>% # count to be filtered on
filter(cat2_cnt > 1) %>% # Ensure >= 2 data points
ungroup %>% # Don't need grouping.
select(-fcnt) # Don't need column anymore
这样的事可能适合你。
修改强>
使用dplyr
比上面的临时变量更好的解决方案。
mydat.zoom <-
filter(mydat, time >80, time < 98) %>% # Your current filtering
group_by(category2) %>% # Using cat2 for this example
filter(n() > 1) %>% # Ensure >= 2 data points
ungroup # Don't need grouping.