根据未在x,y颜色映射/ plot_ly条件文本中使用的次级子组,有条件地为热图单元分配颜色和标签

par*_*nam 6 r heatmap ggplot2 plotly

这是我的数据集的示例:

sampleData <- structure(list(LEVELS = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 
4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 2L, 3L, 1L, 
1L), .Label = c("A", "B", "C", "D"), class = "factor"), GROUP = structure(c(1L, 
1L, 1L, 1L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 2L, 2L, 2L, 2L, 5L, 
5L, 5L, 5L, 1L, 1L, 5L, 1L), .Label = c("AUD", "CTO", "KOP", 
"PIL", "POH"), class = "factor"), MEMBER = structure(c(17L, 18L, 
19L, 20L, 6L, 7L, 3L, 11L, 10L, 2L, 8L, 5L, 12L, 9L, 1L, 4L, 
14L, 15L, 13L, 16L, 17L, 17L, 13L, 19L), .Label = c("AS", "Ca", 
"Fc", "FFZ", "Fg", "Fo", "Fp", "Fv", "GH1", "Lp", "Nb", "Qc", 
"Rq1", "Rt", "Rt2", "Rtcz", "T1", "T2", "T3", "T4"), class = "factor"), 
    VALUE = c(0.001, 1, 0.3, 0.04, 0.1, 0.2, 0.06, 0.08, 0.12, 
    1, 1, 0.3, 0.99, 0.56, 0.54, 0.7, 0.09, 0.1, 0.95, 0.001, 
    0.01, 0.15, 0.005, 0.001)), class = "data.frame", row.names = c(NA, 
-24L))
Run Code Online (Sandbox Code Playgroud)
   LEVELS GROUP MEMBER VALUE
1       A   AUD     T1 0.001
2       B   AUD     T2 1.000
3       C   AUD     T3 0.300
4       D   AUD     T4 0.040
5       A   KOP     Fo 0.100
6       B   KOP     Fp 0.200
7       C   KOP     Fc 0.060
8       D   KOP     Nb 0.080
9       A   PIL     Lp 0.120
10      B   PIL     Ca 1.000
11      C   PIL     Fv 1.000
12      D   PIL     Fg 0.300
13      A   CTO     Qc 0.990
14      B   CTO    GH1 0.560
15      C   CTO     AS 0.540
16      D   CTO    FFZ 0.700
17      A   POH     Rt 0.090
18      B   POH    Rt2 0.100
19      C   POH    Rq1 0.950
20      D   POH   Rtcz 0.001
21      B   AUD     T1 0.010
22      C   AUD     T1 0.150
23      A   POH    Rq1 0.005
24      A   AUD     T3 0.001
Run Code Online (Sandbox Code Playgroud)

我想说明LEVELSy axisGROUPx。如果VALUE < 0.05对应的单元格将是red

但是每个GROUP都有几个MEMBERs。即使MEMBER特定GROUP:LEVELS对中的一个小于0.05,该单元也应为红色GROUP:LEVELS对于该单元被分配为红色,不需要将所有对中的所有成员都小于0.05。但是我想报告MEMBERGROUP:LEVELS对中<0.05 的ALL 的名称。

这是满足此条件的情况的一个示例:

   LEVELS GROUP MEMBER VALUE
1       A   AUD     T1 0.001
24      A   AUD     T3 0.001
Run Code Online (Sandbox Code Playgroud)

因此,如果我将鼠标悬停在单元格上方,则A:AUD希望同时看到它们T1并进行T3报告。

重申

  • 我想确保即使只有一个MEMBER具有红色的单元格也被分配为红色VALUE < 0.05
  • 如果满足该VALUE < 0.05条件的成员不止一个,我想MEMBER在我的密谋文本中报告所有这些名称。

我怎样才能做到这一点?

我当前的代码如下,即使某GROUP:LEVELS对中的一个MEMBER包含红细胞,它似乎也能很好地显示红细胞VALUE < 0.05。但是plotlyMEMBER即使有多个MEMBER,也只报告一个的名称VALUE < 0.05

library(plotly)
library(dplyr)

vals <- unique(scales::rescale(c(sampleData$VALUE)))
o <- order(vals, decreasing = FALSE)
cols <- scales::col_numeric("Blues", domain = NULL)(vals)
colz <- setNames(data.frame(vals[o], cols[o]), NULL)
names(colz) <- c("var","col")
colz$col <- as.character(colz$col)

colz <- dplyr::mutate(colz, col = replace(col, var < 0.05, "#ff3300"))

plotly::plot_ly(data = sampleData,
                x = ~GROUP, 
                y = ~LEVELS,
                z = ~VALUE, 
                type = "heatmap", 
                xgap = 0.5, ygap = 0.2,
                hoverinfo = 'text',
                text = ~paste('</br> Member: ', MEMBER),
                colorscale = colz
)
Run Code Online (Sandbox Code Playgroud)

Stu*_*len 2

解决方案是创建一个新列,其中sampleData将保存标签,然后在调用中plot_ly()引用此新列而不是MEMBER. 通过这种方式,您可以将标签自定义为您喜欢的任何内容 - 因此在这种情况下,我们可以在必要时聚合多个标签,并且仅显示至少一个值 < 0.05 的单元格的标签。

下面插入了新代码,并对调用进行了细微的更改plot_ly()。它的作用是labels通过过滤sampleData值 < 0.05 的行来创建数据框。然后,它通过按LEVELS:GROUP分组来聚合标签- 例如,对于A:AUD,标签将为“T1 T3”。然后这些标签被合并(或者更确切地说join是编辑)回sampleData,并在前面加上“ Member: ”文本,并将标签设置为空字符串,我们不希望在其中显示标签。然后在plot_ly()调用中您只需要引用该label列即可。

library(plotly)
library(dplyr)

vals <- unique(scales::rescale(c(sampleData$VALUE)))
o <- order(vals, decreasing = FALSE)
cols <- scales::col_numeric("Blues", domain = NULL)(vals)
colz <- setNames(data.frame(vals[o], cols[o]), NULL)
names(colz) <- c("var","col")
colz$col <- as.character(colz$col)

colz <- dplyr::mutate(colz, col = replace(col, var < 0.05, "#ff3300"))

# filter data to values < 0.05
labels <- filter(sampleData, VALUE < 0.05)
# aggregate the labels for each unique combination of LEVEL:GROUP
labelsAgg <- aggregate(labels$MEMBER, list(labels$LEVELS, labels$GROUP), paste, collapse = " ")
# set names to match sampleData
labelsAgg <- setNames(labelsAgg, c("LEVELS", "GROUP", "label"))
# prepend "Member" heading, must do this here so that labels we want to be blank are truly blank
labelsAgg$label <- paste("</br> Member: ", labelsAgg$label)
# merge/join labels back with sampleData, using merge() here messed up the factors, so using left_join() is a workaround
sampleData <- left_join(sampleData, labelsAgg,  by = c("LEVELS", "GROUP"))
# replace NA with empty string, otherwise "NA" appears as the label
sampleData[is.na(sampleData$label), "label"] <- ""

# note the text parameter is simply the label now, i.e. the new column sampleData$label
plotly::plot_ly(data = sampleData,
                x = ~GROUP, 
                y = ~LEVELS,
                z = ~VALUE, 
                type = "heatmap", 
                xgap = 0.5, ygap = 0.2,
                hoverinfo = 'text',
                text = ~paste(label),
                colorscale = colz
)
Run Code Online (Sandbox Code Playgroud)

例如,如果您更喜欢逗号分隔符而不是空格,则可以使用塌陷参数轻松更改标签的格式。

如果您愿意,您当然可以稍微整理一下添加的代码,尽管它似乎可以解决问题。

在此输入图像描述