在单个图中获取 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) 的相关文章

  • 如何在一段时间后停止执行?

    我想在一定时间后停止执行 Dash 程序 当我关闭浏览器窗口时效果更好 尽管我怀疑这是否可能 有没有办法通过python中断它 我已经尝试过放一个 sys exit 打电话后app run server 虽然据我了解app run serv
  • 替换列表列表中的元素

    The applyR 中的函数是简化 for 循环以获得输出的好方法 是否有一个等效的函数可以帮助人们在替换向量的值时避免 for 循环 通过示例可以更好地理解这一点 Take this list for example x list li
  • 如何提取与 R 中主题 ID 列表匹配的行?

    我有一个包含许多主题 ID 的数据框 每个主题都有重复观察 我还有一个单独的数据框 其中只有一个主题 ID 列表 我想从更大的数据框中匹配和提取 如何以允许我引用不同数据帧中的SubjectID列表的方式编写代码 不确定我是否完全理解这个问
  • ggplot2可以在一个图例中分别控制点大小和线大小(线宽)吗?

    一个使用的例子ggplot2绘制数据点组和连接每组均值的线 并使用相同的映射aes for shape并为linetype p lt ggplot mtcars aes gear mpg shape factor cyl linetype
  • 将 Instagram/youtube 嵌入 Shiny R 应用程序

    我想通过点击图表来播放 Instagram 或 Youtube 视频 例如显示异常值等 到目前为止 明确告诉 Shiny 视频内容是有效的 require shiny require ggplot2 data df lt data fram
  • 基于另一个数据集获取数据集的子集

    假设我有一个数据集 即 dat1 ID block plot SPID TotHeight 1 1 1 4 44 5 2 1 1 4 51 3 1 1 4 28 7 4 1 1 4 24 5 5 1 1 4 27 3 6 1 1 4 20
  • 是否可以通过扫描从控制台读取而不回显字符?

    这是一个示例函数 passwordEntry lt function cat Enter your password pwd lt scan n 1 what character quiet TRUE invisible pwd 并测试该功
  • 在 R 中创建一个运行计数变量?

    我有一个足球比赛结果的数据集 我希望通过创建一组类似于世界足球 Elo 公式的运行评级来学习 R 我遇到了麻烦 在 Excel 中看似简单的事情在 R 中并不完全直观 例如 4270 个观察中的前 15 个具有必要的变量 date t 1
  • 删除ggplot2中的负图区域[重复]

    这个问题在这里已经有答案了 如何删除 ggplot2 中 x 轴和 y 轴下方的绘图区域 请参见下面的示例 我尝试了几个主题元素 panel border panel margin plot margin 但没有任何运气 p lt ggpl
  • R中的一元加/减是什么?

    来自 R 的详细信息部分Syntax http stat ethz ch R manual R patched library base html Syntax html帮助页面 定义了以下一元和二元运算符 他们被列出 在优先级组中 从最高
  • R - Plm 和 lm - 固定效应

    我有一个平衡面板数据集 df 本质上由三个变量组成 A B and Y 对于一堆独特识别的区域来说 它会随着时间的推移而变化 我想运行一个回归 其中包括区域 下面等式中的区域 和时间 年份 固定效应 如果我没记错的话 我可以通过不同的方式来
  • 使用 pracma::findpeaks 识别持续峰值

    我的语法有问题peakpat内的选项findpeaks内的函数pramcaR 包 v 2 1 1 我使用的是 R 3 4 3 x64 Windows 我希望该函数能够识别可能有两个重复值的峰值 并且我相信该选项peakpat这就是我能做到的
  • 将数据框中的每个 x 个字符拆分为字符串

    我知道这里有一些关于每隔一段时间分割一个字符串的答案nth字符 例如this one https stackoverflow com questions 23208490 split each character in r and this
  • kernlab 中 SVM 训练之外的核矩阵计算

    我正在开发一种新算法 该算法可以生成修改后的核矩阵以用于 SVM 训练 但遇到了一个奇怪的问题 出于测试目的 我比较了使用 kernelMatrix 接口和普通内核接口学习的 SVM 模型 例如 Model with kernelMatri
  • Dendextend:关于如何根据定义的组为树状图的标签着色

    我正在尝试使用一个名为 dendextend 的很棒的 R 包来绘制树状图并根据一组先前定义的组为其分支和标签着色 我已阅读您在 Stack Overflow 中的答案以及 dendextend vignette 的常见问题解答 但我仍然不
  • 在 R 中绘制 Likert 变量的堆积条形图

    假设我有一个如下所示的数据框 P Q1 Q2 1 1 4 1 2 2 3 4 3 1 1 4 其中的列告诉我哪个人相应地回答了问题 q1 q2 中的哪一个 这些问题需要按照 4 分李克特量表进行回答 例如 批准 表示 1 稍微批准 表示 2
  • twitterR 和 ROAuth R 软件包安装

    我在安装 CRAN 上的 twitteR 和 RAOuth 软件包时遇到一些问题 我尝试了几种不同的方法 在 Windows 下使用源代码 在 Ubuntu 下使用 RStudio 我尝试了以下命令 sudo apt get install
  • Purrr::map_df() 删除 NULL 行

    使用时purrr map df 我偶尔会传递一个数据框列表 其中一些项目是NULL 当我做 map df 返回行数少于原始列表的数据框 我想发生的事情是这样的map df calls dplyr bind rows 它忽略了NULL价值观
  • 朴素贝叶斯分类器仅基于先验概率做出决策

    我试图根据推文的情绪将推文分为三类 买入 持有 卖出 我正在使用 R 和包 e1071 我有两个数据框 一个训练集和一组需要预测情绪的新推文 训练集数据框 text sentiment this stock is a good buy Bu
  • 文本挖掘 pdf 文件/词频问题

    我正在尝试挖掘一篇具有丰富 pdf 编码和图表的文章的 pdf 我注意到 当我挖掘一些 pdf 文档时 我得到的高频词是 phi taeoe toe sigma gamma 等 它与某些 pdf 文档配合良好 但与其他文档配合使用时却得到这

随机推荐

  • 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