如何通过填充缺失值从稀疏矩阵生成填充热图
How to generate a filled heatmap from sparse matrix by filling in missing values
数据框有 3 列,id、days 和 sum。我想生成一个总和的热图,其中 id 在 y 轴上,天数在 x 轴上。问题是数据稀疏,因此热图由离散条组成。我希望条形图向右延伸,这样条形图是实心的,并且当总和值发生变化时会改变颜色,并保持该颜色直到第二天的值在右边。
这是生成我正在制作的绘图类型的示例。
library(ggplot2)
set.seed(13)
x_id <- sample( LETTERS[1:5], 100, replace=TRUE,
prob=c(0.15, 0.2, 0.35, 0.1, 0.2) )
x_sum <- sample( c(5, 30, 60, 120, 180, 240, 360), 100, replace=TRUE,
prob=c(.1, .1, .2, .2, .2, .1, .1) )
x_days <- sample.int(2000, 100, replace = TRUE)-1000
df <- data.frame(id = x_id, Days = x_days, sum = x_sum)
ggp <- ggplot(data = df,
mapping = aes(x = Days,
y = id,
fill = sum)) +
geom_tile() +
xlab(label = "Days") + ylab(label = 'id') +
scale_fill_gradient(low = "blue", high = "red")
print(ggp)
我希望颜色向右延伸。我相信这意味着数据框应该按 id 和天数排序,并且必须为每个 id 添加额外的行,以便用 sum 的值和 id 等于 sum / id 的最后一个值来填充缺失的天数。但是我该如何为每个 id 添加行并填写缺失值呢?最右边的颜色应该延长固定长度,以便颜色更明显,比如延长 30 天。
另外,彩图显示了一个临界值。假设临界值是 180。那么对于从零到临界值 (180) 的总和,颜色应该从绿色 (0) 变为黄色 (179),对于高于临界值 (180) 的值,颜色应该从浅红色 (180) 至深红色(最大值或 360)
更新:
这里有一个填充稀疏矩阵的解决方案
library(tidyr)
setkey(DT, id, Days)
DT_fill_NA <- DT[setkey(DT[, .(min(Days):(max(Days)+30)), by = id], id, V1)]
DT_fill <- fill(DT_fill_NA, c('sum'), .direction = "down")
ggp <- ggplot(data = DT_fill,
mapping = aes(x = Days,
y = id,
fill = sum)) +
geom_tile() +
xlab(label = "Days") + ylab(label = 'id') +
scale_fill_gradient(low = "blue", high = "red")
print(ggp)
这将创建稀疏条形向右延伸到下一个条形的图形
现在应该修改颜色图以指示临界值。设临界值为 180。然后对于从零到临界值 (180) 的总和,颜色应从绿色 (0) 变为黄色 (179),对于高于临界值 (180) 的总和,颜色应从浅红色 (180) 至深红色(最大值或 360)
第二次更新
生成在 180 处中断的绿色的一种方法如下
ggp <- ggplot(data = DT_fill,
mapping = aes(x = Days,
y = id,
fill = sum)) +
geom_tile() +
xlab(label = "Days") + ylab(label = 'id') +
scale_fill_gradient2(low = "green", mid = "indianred2", high = "red2",
midpoint = 180, breaks = c(50, 100, 200, 300)) +
theme_bw()
print(ggp)
我不确定这是否清楚地标识了特定值处的断点。如何在临界值(180)处使绿色/红色之间的中断正确?
这是一种从稀疏矩阵生成填充热图并突出显示临界值的方法。
library(ggplot2)
library(data.table)
library(tidyr)
set.seed(13)
n_rows = 200
x_id <- sample( LETTERS[1:5], n_rows, replace=TRUE,
prob=c(0.15, 0.2, 0.35, 0.1, 0.2) )
x_sum <- sample( c(0, 5, 30, 60, 120, 180, 240, 270, 360), n_rows, replace=TRUE,
prob=c(.05, .05, .1, .2, .2, .2, .1, 05, .05) )
x_days <- sample.int(2000, n_rows, replace = TRUE)-1000
DT <- data.table(id = x_id, Days = x_days, sum = x_sum)
setkey(DT, id, Days)
DT_fill_NA <- DT[setkey(DT[, .(min(Days):(max(Days)+100)), by = id], id, V1)]
DT_fill <- fill(DT_fill_NA, c('sum'), .direction = "down")
brks = c(-1, 50, 100, 180, 250, 300, max(DT_fill$sum))
DT_fill$sum_factors = cut(DT_fill$sum, breaks = brks, ordered_result = TRUE, right = TRUE)
unique(DT_fill$sum_factors)
ggp <- ggplot(data = DT_fill,
mapping = aes(x = Days,
y = id,
fill = sum_factors)) +
geom_tile() +
xlab(label = "Days") + ylab(label = 'id') +
scale_fill_manual(values = c("green4", "green3", "green",
"firebrick1", "firebrick3", "firebrick4")) +
theme_bw()
print(ggp)
数据框有 3 列,id、days 和 sum。我想生成一个总和的热图,其中 id 在 y 轴上,天数在 x 轴上。问题是数据稀疏,因此热图由离散条组成。我希望条形图向右延伸,这样条形图是实心的,并且当总和值发生变化时会改变颜色,并保持该颜色直到第二天的值在右边。
这是生成我正在制作的绘图类型的示例。
library(ggplot2)
set.seed(13)
x_id <- sample( LETTERS[1:5], 100, replace=TRUE,
prob=c(0.15, 0.2, 0.35, 0.1, 0.2) )
x_sum <- sample( c(5, 30, 60, 120, 180, 240, 360), 100, replace=TRUE,
prob=c(.1, .1, .2, .2, .2, .1, .1) )
x_days <- sample.int(2000, 100, replace = TRUE)-1000
df <- data.frame(id = x_id, Days = x_days, sum = x_sum)
ggp <- ggplot(data = df,
mapping = aes(x = Days,
y = id,
fill = sum)) +
geom_tile() +
xlab(label = "Days") + ylab(label = 'id') +
scale_fill_gradient(low = "blue", high = "red")
print(ggp)
我希望颜色向右延伸。我相信这意味着数据框应该按 id 和天数排序,并且必须为每个 id 添加额外的行,以便用 sum 的值和 id 等于 sum / id 的最后一个值来填充缺失的天数。但是我该如何为每个 id 添加行并填写缺失值呢?最右边的颜色应该延长固定长度,以便颜色更明显,比如延长 30 天。
另外,彩图显示了一个临界值。假设临界值是 180。那么对于从零到临界值 (180) 的总和,颜色应该从绿色 (0) 变为黄色 (179),对于高于临界值 (180) 的值,颜色应该从浅红色 (180) 至深红色(最大值或 360)
更新:
这里有一个填充稀疏矩阵的解决方案
library(tidyr)
setkey(DT, id, Days)
DT_fill_NA <- DT[setkey(DT[, .(min(Days):(max(Days)+30)), by = id], id, V1)]
DT_fill <- fill(DT_fill_NA, c('sum'), .direction = "down")
ggp <- ggplot(data = DT_fill,
mapping = aes(x = Days,
y = id,
fill = sum)) +
geom_tile() +
xlab(label = "Days") + ylab(label = 'id') +
scale_fill_gradient(low = "blue", high = "red")
print(ggp)
这将创建稀疏条形向右延伸到下一个条形的图形
现在应该修改颜色图以指示临界值。设临界值为 180。然后对于从零到临界值 (180) 的总和,颜色应从绿色 (0) 变为黄色 (179),对于高于临界值 (180) 的总和,颜色应从浅红色 (180) 至深红色(最大值或 360)
第二次更新
生成在 180 处中断的绿色的一种方法如下
ggp <- ggplot(data = DT_fill,
mapping = aes(x = Days,
y = id,
fill = sum)) +
geom_tile() +
xlab(label = "Days") + ylab(label = 'id') +
scale_fill_gradient2(low = "green", mid = "indianred2", high = "red2",
midpoint = 180, breaks = c(50, 100, 200, 300)) +
theme_bw()
print(ggp)
我不确定这是否清楚地标识了特定值处的断点。如何在临界值(180)处使绿色/红色之间的中断正确?
这是一种从稀疏矩阵生成填充热图并突出显示临界值的方法。
library(ggplot2)
library(data.table)
library(tidyr)
set.seed(13)
n_rows = 200
x_id <- sample( LETTERS[1:5], n_rows, replace=TRUE,
prob=c(0.15, 0.2, 0.35, 0.1, 0.2) )
x_sum <- sample( c(0, 5, 30, 60, 120, 180, 240, 270, 360), n_rows, replace=TRUE,
prob=c(.05, .05, .1, .2, .2, .2, .1, 05, .05) )
x_days <- sample.int(2000, n_rows, replace = TRUE)-1000
DT <- data.table(id = x_id, Days = x_days, sum = x_sum)
setkey(DT, id, Days)
DT_fill_NA <- DT[setkey(DT[, .(min(Days):(max(Days)+100)), by = id], id, V1)]
DT_fill <- fill(DT_fill_NA, c('sum'), .direction = "down")
brks = c(-1, 50, 100, 180, 250, 300, max(DT_fill$sum))
DT_fill$sum_factors = cut(DT_fill$sum, breaks = brks, ordered_result = TRUE, right = TRUE)
unique(DT_fill$sum_factors)
ggp <- ggplot(data = DT_fill,
mapping = aes(x = Days,
y = id,
fill = sum_factors)) +
geom_tile() +
xlab(label = "Days") + ylab(label = 'id') +
scale_fill_manual(values = c("green4", "green3", "green",
"firebrick1", "firebrick3", "firebrick4")) +
theme_bw()
print(ggp)