在单个图中获取 geom_hex 中的观测值 (Shiny)

2024-05-05

我正在尝试创建一个十六进制的交互式图,用户可以单击给定的十六进制,并接收分组在该单击的十六进制中的原始数据帧的所有观察结果的列表。

下面是一个 MWE,看起来非常接近我的目标。我正在使用 Shiny、hexbin() 和 ggplotly。

app.R

library(shiny)
library(plotly)
library(data.table)
library(GGally)
library(reshape2)
library(hexbin)

ui <- fluidPage(
  plotlyOutput("plot"),
  verbatimTextOutput("click")
)

server <- function(input, output, session) {
  #Create data
  set.seed(1)
  bindata <- data.frame(x=rnorm(100), y=rnorm(100))

  h <- hexbin (bindata, xbins = 5, IDs = TRUE, xbnds = range (bindata$x), ybnds = range (bindata$y))

  # As we have the cell IDs, we can merge this data.frame with the proper coordinates
  hexdf <- data.frame (hcell2xy (h),  ID = h@cell, counts = h@count)

  # I have tried different methods of generating the ggplot object
  #p <- ggplot(hexdf, aes(x=x, y=y, fill = counts)) + geom_hex(stat="identity")
  #p <- ggplot(hexdf, aes(x=x, y=y, fill = ID)) + geom_hex(stat="identity")
  #p <- ggplot(hexdf, aes(x=x, y=y, fill = counts, colours = ID)) + geom_hex(stat="identity")
  #p <- ggplot(hexdf, colours = ID, aes(x=x, y=y, colours = ID, fill = counts)) + geom_hex(stat="identity")
  p <- ggplot(hexdf, aes(x=x, y=y, fill = counts, ID=ID)) + geom_hex(stat="identity")

  output$plot <- renderPlotly({
    ggplotly(p)
  })

  d <- reactive(event_data("plotly_click"))

  output$click <- renderPrint({
    if (is.null(d())){
      "Click on a state to view event data"
    }
    else{
      str(d())
      #Next line would deliver all observations from original data frame (bindata) that are in the clicked hexbin... if d() from event_data() was returning ID instead of curveNumber
      #bindata[which(h@cID==d()$curveNumber),]
    }
  })
}

shinyApp(ui, server)

h@cID 对象内部是所有数据点的 ID(显示哪个数据点进入哪个 hexbin)。因此,我觉得如果我能够在用户点击时让 event_data() 返回 hexbin ID,那么我应该能够成功地将 hexbin ID 映射回 h@cID 对象以获得相应的数据点。

不幸的是,按照我目前的编写方式,event_data() 将返回“curveNumber”,它似乎不等于 ID。它似乎也没有转换为 ID(即使使用 h 对象中的所有信息 - 不仅仅是 h@cID,还包括 h@xcm、h@ycm 等)

有没有人知道解决此类问题的方法?任何想法,将不胜感激!

注意:我最近的两篇文章(包括赏金)与这个问题非常相似。他们位于这里(ggplotly 中使用 geom_hex() 散点图进行交互式选择 https://stackoverflow.com/questions/41409890/interactive-selection-in-ggplotly-with-geom-hex-scatterplot) and (使用plotly和Shiny获取geom_hex中的观测值 https://stackoverflow.com/questions/41583889/obtain-observations-in-geom-hex-using-plotly-and-shiny)。不同的是,我每一步都让问题变得更加简单。谢谢。

编辑 - 可能的答案

我想我可能已经找到了这个问题的解决方案。就像 @oshun 注意到的那样,从 event_data() 返回的 curveNumber 和 hexbin ID 之间存在一些隐藏的转换。似乎 curveNumbers 首先通过增加十六进制数从最小到最大排序。然后,在给定的计数内,curverNumber 似乎通过增加 ID 进一步从小到大排序。但是,ID 是按特点 (not number)。例如,数字 18 将被视为小于数字 2,因为 18 以数字 1 开头,而数字 1 小于数字 2。

当本示例中的完整数据集用下面的 count、ID 和 curveNumber 表示时,您可以看到这种模式:

count=1 (ID=24) —> curveNumber 0
count=1 (ID=26) —> curveNumber 1
count=1 (ID=34) —> curveNumber 2
count=1 (ID=5) —> curveNumber 3
count=1 (ID=7) —> curveNumber 4
count=2 (ID=11) —> curveNumber 5
count=2 (ID=14) —> curveNumber 6
count=2 (ID=19) —> curveNumber 7
count=2 (ID=23) —> curveNumber 8
count=2 (ID=3) —> curveNumber 9
count=2 (ID=32) —> curveNumber 10
count=2 (ID=4) —> curveNumber 11
count=3 (ID=10) —> curveNumber 12
count=3 (ID=13) —> curveNumber 13
count=3 (ID=33) —> curveNumber 14
count=3 (ID=40) —> curveNumber 15
count=3 (ID=9) —> curveNumber 16
count=4 (ID=17) —> curveNumber 17
count=4 (ID=20) —> curveNumber 18
count=5 (ID=28) —> curveNumber 19 
count=5 (ID=8) —> curveNumber 20
count=6 (ID=21) —> curveNumber 21 
count=8 (ID=27) —> curveNumber 22 
count=9 (ID=22) —> curveNumber 23 
count=11 (ID=16)—> curveNumber 24
count=14 (ID=15)—> curveNumber 25

下面是我对这个问题的初步解决方案。我很确定它适用于此this数据集,但我计划在更多数据集上测试它以确定。

app.R

library(shiny)
library(plotly)
library(data.table)
library(GGally)
library(reshape2)
library(hexbin)

ui <- fluidPage(
  plotlyOutput("plot"),
  verbatimTextOutput("click")
)

server <- function(input, output, session) {

  # Curve number to ID
  cnToID <- function(h){
    df <- data.frame(table(h@cID))
    colnames(df) <- c("ID","count")
    cnID <- df[order(df$count,as.character(df$ID)),]
    cnID$curveNumber <- seq(0, nrow(cnID)-1)
    return(cnID)
  }

  # Create data
  set.seed(1)
  bindata <- data.frame(x=rnorm(100), y=rnorm(100))
  h <- hexbin (bindata, xbins = 5, IDs = TRUE, xbnds = range (bindata$x), ybnds = range (bindata$y))
  hexdf <- data.frame (hcell2xy (h),  ID = h@cell, counts = h@count)
  p <- ggplot(hexdf, aes(x=x, y=y, fill = counts, ID=ID)) + geom_hex(stat="identity")
  #p <- ggplot(hexdf, aes(x=x, y=y, fill = counts), ID=ID) + geom_hex(stat="identity")
  cnID <- cnToID(h)

  output$plot <- renderPlotly({
    p2 <- ggplotly(p)
    for (i in 1:nrow(hexdf)){
      p2$x$data[[i]]$text <- gsub("<.*$", "", p2$x$data[[i]]$text)
    }
    p2
  })

  d <- reactive(event_data("plotly_click"))

  output$click <- renderPrint({
    if (is.null(d())){
      "Click on a state to view event data"
    }
    else{
      clickID <- as.numeric(as.character(cnID[which(cnID$curveNumber==d()$curveNumber),]$ID))
      clickID
      bindata[which(h@cID==clickID),]
    }
  })
}

shinyApp(ui, server)

Edit 2:


足够简化您的问题,以便我可以给您部分答案。下面的代码允许您单击分箱数据(绘制为正方形)并获取原始数据。

情节返回信息点击事件 https://plot.ly/r/shiny-coupled-events/形式为x, y, curveNumber and pointNumber. curveNumber索引跟踪,但这似乎取决于绘图的调用方式。pointNumber似乎根据数据的顺序进行索引(并且它也链接到curveNumber)。如果仅绘制一组点,则映射到原始数据相对简单。

下面的解决方案适用于点,因为它使用pointNumber (x and y可能是更好的查找组合,因为这些是绝对值而不是相对顺序)。该解决方案不适用于geom_hex正如您最初要求的六边形,因为只有curveNumber单击鼠标即可返回。看起来六边形首先通过计数添加,然后通过其他一些排序变量添加。解决背后的原理curveNumber如果你想使用的话,编号是关键geom_hex.

下面是两个屏幕截图: 左 = 原始图geom_hex。右 = 修改后的图geom_point using pointNumber正确索引结果。

修改后的代码如下。 OP和我都大量借鉴了这个answer https://stackoverflow.com/a/14586941/4718512关于六边形。

library(shiny); library(plotly); library(GGally); library(reshape2); library(hexbin)

ui <- fluidPage(
  plotlyOutput("plot"),
  checkboxInput("squarePoints", label = "Switch to points?"),
  verbatimTextOutput("click"),
  HTML("Check the work:"),
  plotlyOutput("plot1")
)

server <- function(input, output, session) {
  #Create data
  set.seed(1)
  bindata <- data.frame(myIndex = factor(paste0("ID",1:100)), 
                        x=rnorm(100), y=rnorm(100))

  h <- hexbin (bindata[,2:3], xbins = 5, IDs = TRUE, 
               xbnds = range(bindata$x), ybnds = range(bindata$y))

  # As we have the cell IDs, we can merge this data.frame with the proper coordinates
  hexdf <- data.frame (hcell2xy (h),  ID = h@cell, counts = h@count)

  #New code added below ###
  counts <- hexTapply(h, bindata$myIndex, table)  #list of 26
  counts <- t(simplify2array (counts))
  counts <- melt (counts)                 #2600 rows = 26 hexagons * 100 observations
  colnames (counts)  <- c ("ID", "myIndex", "present")

  allhex <- merge (counts, hexdf)         #2600 rows = 26 hexagons * 100 observations
  #rename hex coordinates
  names(allhex)[names(allhex) %in% c("x", "y")] <- c("hex.x", "hex.y")  
  allhex <- merge(allhex, bindata)
  somehex <- allhex[allhex$present > 0,]  #100 rows (original data)

  #Plotly graphs objects in a certain order, so sort the lookup data by the same order 
  #in which it's plotted.
  #No idea how curveNumber plots data. First by counts, then by ...?
  #pointNumber seems more straightforward. 
  sorthex <- hexdf[with(hexdf, order(ID)), ]

  #Create a switch to change between geom_hex() and geom_point()
  switchPoints <- reactive(if(input$squarePoints) {
    geom_point(shape = 22, size = 10)
    } else {  
      geom_hex(stat = "identity")
      })

  hexdf$myIndex <- "na" #Added here for second plotly
  ### New code added above ###

  p <- reactive(ggplot(hexdf, aes(x=x, y=y, fill = counts))  + coord_equal() +
                switchPoints() )

  output$plot <- renderPlotly({
    ggplotly(p())
  })

  d <- reactive(event_data("plotly_click"))
  #pointNumber = index starting from 0
  hexID <- reactive(sorthex[d()$pointNumber + 1, "ID"]) 

  output$click <- renderPrint({
    if (is.null(d())){
      "Click on a state to view event data"
    }
    else{
      list(
      str(d()),
      somehex[somehex$ID == hexID(),]
      )
    }
  })

  #Check your work: plot raw data over hexagons
  p.check <- ggplot(hexdf, aes(x=x, y=y, fill = counts)) + geom_hex(stat="identity") +
    geom_point(data = somehex, aes(x=x, y=y)) + coord_equal()

  output$plot1 <- renderPlotly({
    ggplotly(p.check + aes(label= myIndex) )
  })


}

shinyApp(ui, server)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在单个图中获取 geom_hex 中的观测值 (Shiny) 的相关文章

  • 从 n,k 维矩阵数组中减去 n,k 维矩阵

    如果我有一个数组A A lt array 0 c 4 3 5 for i in 1 5 set seed i A i lt matrix rnorm 12 4 3 如果我有矩阵 B set seed 6 B lt matrix rnorm
  • R、Rcpp 与 Armadillo 中矩阵 rowSums() 与 colSums() 的效率

    背景 来自 R 编程 我正在扩展到 C C 形式的编译代码Rcpp 作为循环交换 以及一般的 C C 效果的实践练习 我实现了 R 的等效项rowSums and colSums 矩阵的函数Rcpp 我知道它们以 Rcpp 糖的形式存在 并
  • 在 R 传单中添加不透明度滑块

    如何在 R leaflet 应用程序中添加滑块来控制特定图层的不透明度 对于这个应用程序 我不想使用闪亮 这里建议 在 R 传单应用程序中添加滑块 https stackoverflow com questions 37682619 add
  • R - 计算 bin 中特定值的数量

    我有一个如下所示的数据框 df Value lt c 1 1 0 2 1 3 4 0 0 1 2 0 3 0 4 5 2 3 0 6 Sl lt c 1 20 df lt data frame Sl Value gt df Sl Value
  • 使用officer R导出时如何提高ggplots的分辨率

    我想将图表导出到 PPT 并使用Officer 包来实现相同的目的 但是 图表的默认分辨率较低 我想更改它 我目前正在使用以下电话 ph with gg p1 type chart res 1200 其中 p1 是 ggplot 对象 运行
  • 不同编程语言中的浮点数学

    我知道浮点数学充其量可能是丑陋的 但我想知道是否有人可以解释以下怪癖 在大多数编程语言中 我测试了 0 4 到 0 2 的加法会产生轻微的错误 而 0 4 0 1 0 1 则不会产生错误 两者计算不平等的原因是什么 在各自的编程语言中可以采
  • 如何在 Shiny 中提取动态生成的输入值?

    我正在创建一个闪亮的应用程序 它将根据客户的不同功能为客户生成分数 在我闪亮的应用程序中 我提供了 checkboxGroupInput 来选择所需的功能 根据所选功能 应用程序将动态地将 numericInput 添加到 Web ui 以
  • 如何按时间间隔匹配数据帧?

    这是我从数据记录器导入原始数据时经常出现的问题 温度记录仪设置为每十分钟记录一次温度 单独的气体记录仪设置为记录最后十分钟间隔内使用的气体 我想将这两个记录器的数据合并到一个数据框中进行绘图和分析 但时间并不完全一致 我希望每十分钟的时间段
  • 如何纠正 data.frame 上的字符编码

    我有一个像这样的数据框 data names lt data frame DATA c 1 5 rownames data names lt c IV xc1N JOS xc9 LUC xcdA RAM xd3N TO xd1O data
  • 多个动态滤镜更新闪亮

    我希望能够让 UI 输入闪亮 并根据用户之前的选择进行自我更新 因此 在下面的示例中 预期的行为是用户选择cyl vsor carb那么这将 过滤数据集mtcars用于创建绘图 即用户根据过滤条件调整绘图并 更新其他过滤器中的剩余输入选择
  • 为什么 sapply 的缩放速度比样本大小的 for 循环慢?

    假设我想采用向量 X 2 1 N 并将 e 计算为每个元 素的指数 是的 我认识到最好的方法就是通过向量化 exp X 但这样做的目的是将 for 循环与 sapply 进行比较 我通过逐步尝试三种方法 一种使用 for 循环 两种以不同方
  • `dplyr::_join` 函数的命名向量“by”参数[重复]

    这个问题在这里已经有答案了 我正在写一个函数dplyr join两个数据框by不同的列 第一个数据帧的列名称动态指定为函数参数 我相信我需要使用rlang准引用 元编程 但未能找到可行的解决方案 我很感激任何建议 library dplyr
  • 更新 R6 对象实例中的方法定义

    如何更新 R6 类实例的方法定义 正如我所期望的 S3 使用当前的方法定义 对于 R5 参考类 我可以使用 myInstance myInstance copy 在 R6 中 我尝试了 myInstance myInstance clone
  • 闪亮的应用程序包:css 和所有 www/ 目录内容

    我正在尝试将 Shiny 应用程序转换为 R 包 但我在处理有关 www 目录以及 松散 文件的所有问题时遇到了问题 我闪亮的应用程序运行得很好 但是当我尝试 打包它 时 它不起作用 我闪亮的应用程序目录 my shiny app R ut
  • R - 重塑 - 熔化错误

    我正在尝试融化数据框 但出现了这个奇怪的错误 有什么想法吗 str zx7 data frame 519 obs of 5 variables calday new Date format 2011 01 03 2011 01 04 201
  • R,使用具有两种以上可能性的二项式分布

    我知道这可能是基本的 但我似乎有一个心理障碍 假设您想要计算在一个骰子上掷出 4 5 或 6 的概率 在 R 中 这很简单 sum 1 6 1 6 1 6 这给出了 1 2 这是正确答案 然而 我内心深处 可能应该保留的地方 认为我应该能够
  • 在网格中制作一个矩形图例,并标记行和列

    我有一个 ggplot 我将因子映射到填充和 alpha 如下所示 set seed 47 the data lt data frame value rpois 6 lambda 20 cat1 rep c A B each 3 cat2
  • data.table 抛出“找不到对象”错误[重复]

    这个问题在这里已经有答案了 我有一个数据表 library data table mydt lt data table index 1 10 当我在全局环境中尝试它时 我可以让它工作 但当我在调试器中或在包测试中使用它时却无法工作 问题是我
  • 要在子集中显示的非数字条目的维恩图

    我有以下数据框 SET1 SET2 SET3 par1 par2 par1 par2 par3 par2 par3 par4 par5 我想制作一个维恩图 其中所有这些 parX 元素都显示在各自的子集中 即作为标签 而不仅仅是重叠元素的数
  • 当将遗传算法与 lme4 一起使用时,glmulti 无限期运行

    我在 R 中使用 glmulti 进行模型平均 我的模型中有大约 10 个变量 使得详尽的筛选不切实际 因此我需要使用遗传算法 GA 调用 method g 我需要包含随机效应 因此我使用 glmulti 作为 lme4 的包装器 此处提供

随机推荐

  • EF7 中的脚手架不再产生“setter”

    我试图将我的个人项目从 Net 6 升级到 7 主要是为了找出重大更改 因此 我预计有些东西需要返工 情况总是如此 如果在某个时候我敢于完成这个项目 那么它就是一个非营利项目 但目前的情况还远未实现 作为现在的上下文 我正在管理一个包含类别
  • 如何在 R 或 MATLAB 中为散点图创建阴影误差条“框”

    我想在 R 或 MATLAB 中创建一个简单的散点图 涉及两个变量 x 和 y 它们有与之相关的错误 epsilon x 和 epsilon y 然而 我不是添加误差线 而是希望在每个 x y 对周围创建一个 阴影框 其中框的高度范围从 y
  • Django 管理员使用 JWT

    Using 姜戈 1 11 Python 3 6 FE 中的 DRF 与 JWT 我知道 Django 管理员使用会话和基本身份验证 到目前为止我所做的 用 AWS Cognito 替换了 Django 管理员身份验证登录页面 用户转到do
  • Vim / vi 生存指南

    基本的 vim 命令有哪些 新用户需要了解什么才能避免陷入麻烦 请每条评论一条命令 我发现不可替代的 因为它也可以在 vi 中使用 与 vim 的视觉模式不同 是标记 您可以用以下标记标记不同的点m 小写 然后是您选择的字母 例如 x 然后
  • 如何使使用 CSS :after 元素创建的文本可选择?

    我正在使用 css 创建文本 after 但我无法选择生成的文本 例如用于复制和粘贴 是否可以使其可选择 div foo div div after content 123 sample http jsfiddle net jfbc4 2
  • 如何将点光源转换为卵形/椭圆形?

    我希望通过具有不同 x 和 y 值的 vec2 半径将当前的圆形光变成椭圆形 有没有办法根据我当前在片段着色器中的代码来做到这一点 uniform struct Light vec4 colour vec3 position vec2 ra
  • SVG/XML 中有一些innerHTML 替代品吗?

    在 HTML 中 我可以通过提供字符串形式的模板来构建一个简单的模板系统 替换其中的某些部分 然后使用innerHTML到某个容器 var templ span myText span var newContent templ replac
  • 如何动态构造方法?

    我设计了一个类 它非常标准 具有一些方法属性 class foo def f1 self print f1 def f2 self print f2 def fn self print fn 现在我想创建一个包含一组 foo 实例的类 cl
  • 是否有用于序列化和反序列化各种格式的对象层次结构的模式?

    给定一个复杂的对象层次结构 幸运的是它不包含循环引用 如何实现支持各种格式的序列化 我不是来讨论实际实施的 相反 我正在寻找可能派上用场的设计模式的提示 更准确地说 我正在使用 Ruby 我想解析 XML 和 JSON 数据以构建复杂的对象
  • Checkstyle 规则防止调用某些方法和构造函数

    是否可以使用 Checkstyle 来禁止使用某些使用系统相关默认值 区域设置 字符集等 的构造函数或方法 我更喜欢强制执行一项政策 程序员应该明确了解系统相关的值 所以我认为以下物品是危险的 all the constructors of
  • 是否需要 AudioServicesDisposeSystemSoundID?

    我最近开始使用 AudioToolbox 框架 并注意到有一个名为AudioServicesDisposeSystemSoundID 只是想知道 调用的时候不调用上面的方法是不是内存泄漏AudioServicesCreateSystemSo
  • TortoiseGit 与 TortoiseSVN 并存?

    我已经使用 TortoiseSVN 好几年了 但我正在考虑慢慢改用 git 因为我真的很喜欢它的分支和合并 我目前正在通过命令行使用 git 但正在考虑安装 TortoiseGit 有人有并排使用两只乌龟的经验吗 这有什么已知的问题吗 我真
  • TensorFlow 未编译为使用 SSE(等)指令,但这些指令是可用的

    我第一次使用一些示例代码运行 TensorFlow 运行代码时我收到以下警告 有谁知道为什么会发生这种情况以及如何解决它 2017 03 31 02 12 59 346109 W c tf jenkins home workspace re
  • 如何使用 Objective C 安全地存储数据? (Mac/可可开发)

    我正在尝试创建我的可可应用程序的试用部分 我已设置所有许可 包括密钥 等 但我想知道如何存储例如用户第一次在安全的地方运行程序的时间 用户无法轻松找到它和 或编辑它 我正在摆弄 NSUserDefaults standardUserDefa
  • CvMat 和 Imread 与 IpImage 和 CvLoadImage

    使用 OpenCv 2 4 我有两个选项来加载图像 1 CvMat and Imread 2 IpImage and CvLoadImage 使用哪一个更好 我尝试将两者混合并最终出现段错误 imread返回一个Mat not CvMat
  • tf.keras.utils.image_dataset_from_directory,但标签来自 csv?

    请告诉我哪里出错了 我正在研究 Kaggle 狗品种分类挑战 我想尝试 one hot 编码与标签编码 图像未在图像目录中拆分 因此我无法将 推断 与 tf keras utils image dataset from directory
  • Android 1.5 在设备上不再显示 Android 应用程序

    我在 Android Market 上的最新更新导致我的应用程序不再适用于 Android 1 5 设备 我更改了以下内容
  • Sequel Pro / MAMP 在哪里存储本地数据库?

    我通过 Sequel Pro 和 MAMP 在我的计算机上创建了一些数据库 并运行 localhost 来查看它们 但是 我全新安装了 Mac OS Lion 但忘记将数据库备份到 sql 文件 我会定期备份文件 并预装计算机的副本 有谁知
  • JavaFX 自定义列表单元格,updateItem 被多次调用

    我正在使用一个ListView在 JavaFX 应用程序中 列表中的项目需要的不仅仅是一个字符串来显示它们 所以我做了一个自定义实现ListCell
  • 在单个图中获取 geom_hex 中的观测值 (Shiny)

    我正在尝试创建一个十六进制的交互式图 用户可以单击给定的十六进制 并接收分组在该单击的十六进制中的原始数据帧的所有观察结果的列表 下面是一个 MWE 看起来非常接近我的目标 我正在使用 Shiny hexbin 和 ggplotly app