R Shiny中的数据争用:在k-means聚类分析后绘制新争用的数据

R Shiny中的数据争用:在k-means聚类分析后绘制新争用的数据,r,ggplot2,shiny,k-means,data-wrangling,R,Ggplot2,Shiny,K Means,Data Wrangling,我正在尝试构建一个数据分析仪表板,我正在使用Shiny,这是我相对较新的。我的仪表板的一个功能是对用户生成的数据使用k-means聚类。我可以让聚类分析正常工作,但我希望在完成初始聚类分析后,能够对单个聚类进行探索性数据分析。此外,我还希望使用Shiny中的被动数据帧来实现这一点,这样,如果用户更改仪表板上的值,分析将刷新,包括聚类后的探索性内容 首先,以下是我在仪表板服务器代码和相关库中使用的一些函数,请先运行这些函数:- #libraries=========================

我正在尝试构建一个数据分析仪表板,我正在使用Shiny,这是我相对较新的。我的仪表板的一个功能是对用户生成的数据使用k-means聚类。我可以让聚类分析正常工作,但我希望在完成初始聚类分析后,能够对单个聚类进行探索性数据分析。此外,我还希望使用Shiny中的被动数据帧来实现这一点,这样,如果用户更改仪表板上的值,分析将刷新,包括聚类后的探索性内容

首先,以下是我在仪表板服务器代码和相关库中使用的一些函数,请先运行这些函数:-

#libraries===================================================================
library(ids)
library(tidyverse)
library(dplyr)
library(shiny)
library(ggplot2)
library(shinydashboard)
library(shinyWidgets)
library(factoextra)

#functions required==========================================================
#scale https://stackoverflow.com/questions/35775696/trying-to-use-dplyr-to-group-by-and-apply-scale
scale_this <- function(x){
  (x - mean(x, na.rm=TRUE)) / sd(x, na.rm=TRUE)
}


#wss plot 

wssplot <- function(data, nc = 15, seed = 1234) {
  wss <- (nrow(data) - 1) * sum(apply(data, 2, var))
  for (i in 2:nc) {
    set.seed(seed)
    wss[i] <- sum(kmeans(data, centers = i)$withinss)
  }
  plot(1:nc,
       wss,
       type = "b",
       xlab = "Number of Clusters",
       ylab = "Within groups sum of squares")
}
这是我得到的,请参见错误消息:-

很可能是我做错了什么,但任何指向正确方向的指针都将受到赞赏!提前感谢:)

您需要对所有
输入$abc
变量使用
req()
,并且
eval\u tidy
因为它们不是标准变量。对服务器功能进行如下所示的小更新将解决您的问题

server<-function(input,output,session){
  
  #create reactive dataframe
  rval_df <-reactive({
    mockdf
  })
   
  #=============================================kmeans clustering==================================================
  rval_UserData<-reactive({
    req(input$userselect)
    userselect <- eval_tidy(input$userselect)
    rval_df()%>%
      filter(randomid %in% userselect)%>%
      group_by(randomid)%>%
      summarise(Count=n(),MeanDuration=mean(Duration),SDDuration=sd(Duration))%>%
      mutate(SDDuration=if_else(is.na(SDDuration),0,SDDuration),
             Cluster=as.factor(rval_kclust()$cluster))
    
  })
  
  #create a scaled dataset for the clustering
  rval_cluster_df<-reactive({
    req(input$userselect)
    userselect <- eval_tidy(input$userselect)
    rval_df()%>%    
      filter(randomid %in% userselect)%>%
      group_by(randomid)%>%
      summarise(Count=n(),MeanDuration=mean(Duration),SDDuration=sd(Duration))%>%
      mutate(SDDuration=if_else(is.na(SDDuration),0,SDDuration),
             Count=scale_this(Count),
             MeanDuration=scale_this(MeanDuration),
             SDDuration=scale_this(SDDuration))%>%
      select(Count,MeanDuration,SDDuration)
    
  }) 
  
  #cluster algorithm
  rval_kclust<-reactive({
    req(input$ksolution)
    centers <- as.numeric(eval_tidy(input$ksolution))
    kmeans(rval_cluster_df(), centers = centers)
  })
  
  output$clustplot<-renderPlot({
    
    factoextra::fviz_cluster(rval_kclust(), data = rval_cluster_df()) 
    
  })
  
  
  output$elbowplot<-renderPlot({
    
    wssplot(rval_cluster_df())
  })
  
  output$Clusterdf<- DT::renderDataTable({
    rval_UserData()
    
  })
  
  rval_cluster_merged_df<-reactive({
    
    merge(rval_df(), rval_UserData(), by="randomid")

  })

  output$clust_dens<-renderPlot({
    
    dd<-rval_cluster_merged_df()
    
    ggplot(dd,aes(x=Duration, colour=Cluster, group=Cluster))+
      geom_density()+ggtitle("Cluster density plot")+scale_x_log10()
    
  })
  
}
server%
变异(SDDuration=if_else(is.na(SDDuration),0,SDDuration),
Cluster=as.factor(rval_kclust()$Cluster))
})
#为集群创建缩放数据集
rval_集群_df%
分组依据(随机ID)%>%
总结(计数=n(),平均持续时间=mean(持续时间),SDDuration=sd(持续时间))%>%
变异(SDDuration=if_else(is.na(SDDuration),0,SDDuration),
计数=此(计数)的刻度,
平均持续时间=此(平均持续时间)的比例,
SDDuration=缩放此(SDDuration))%>%
选择(计数、平均持续时间、SDDuration)
}) 
#聚类算法

rval_kclustHi@YBS,感谢您的回复。我应该如何修改密度图的代码(在我上传图像之前的代码部分)。我曾尝试在代码中添加req()函数,但没有成功。抱歉,我需要一段时间才能理解这些新功能!我明白了,您的OP的单独部分中有密度图代码。您的密度图在更新的服务器代码答案中。@RobinTurkington,通常认为接受回答您的问题的答案是礼貌的。您好@YBS。我已经接受了你的解决方案,因为我现在只想看看:)谢谢你的帮助
#UI============================================================================

ui<-fluidPage(
  titlePanel('Minimal example'),
  tabsetPanel(
    
    
    #=============================================kmeans clustering==================================================
    
    
    tabPanel("User Type Discovery",
             sidebarLayout(
               sidebarPanel(width = 4,numericInput('ksolution', 'Select k solution', 5),
                            pickerInput('userselect', 'Which users do you want to include:', 
                                        choices = unique(mockdf$randomid), options = list('actions-box'=TRUE),multiple = T)),
               mainPanel(fluidRow(
                 column(12, plotOutput("elbowplot")),
                 column(12, plotOutput("clustplot")),
                 column(12, plotOutput("clust_dens")),
                 column(12, DT::dataTableOutput('Clusterdf'))))
             )
    )
  )
)
                 

#SERVER===========================================================
server<-function(input,output,session){

  
  
  
  #create reactive dataframe
  rval_df <-reactive({
    mockdf
  })
  
  
  
  #=============================================kmeans clustering==================================================
  
  
  
  rval_UserData<-reactive({
    
    rval_df()%>%
      filter(randomid %in% input$userselect)%>%
      group_by(randomid)%>%
      summarise(Count=n(),MeanDuration=mean(Duration),SDDuration=sd(Duration))%>%
      mutate(SDDuration=if_else(is.na(SDDuration),0,SDDuration),
      Cluster=as.factor(rval_kclust()$cluster))
    
  })
  
  
  #create a scaled dataset for the clustering
  rval_cluster_df<-reactive({
    
    
    rval_df()%>%    
      filter(randomid %in% input$userselect)%>%
      group_by(randomid)%>%
      summarise(Count=n(),MeanDuration=mean(Duration),SDDuration=sd(Duration))%>%
      mutate(SDDuration=if_else(is.na(SDDuration),0,SDDuration),
             Count=scale_this(Count),
             MeanDuration=scale_this(MeanDuration),
             SDDuration=scale_this(SDDuration))%>%
      select(Count,MeanDuration,SDDuration)
    
    
  })  
  
  
  
  #cluster algorithm
  rval_kclust<-reactive({
    kmeans(rval_cluster_df(), centers = input$ksolution)
  })
  
  
  
  
  output$clustplot<-renderPlot({
    
    
    
    
    factoextra::fviz_cluster(rval_kclust(), data = rval_cluster_df()) 
    
    
  })
  
  
  output$elbowplot<-renderPlot({
    
    wssplot(rval_cluster_df())
  })
  
  
  output$Clusterdf<- DT::renderDataTable({
    rval_UserData()
    
  })
  
  
}


shinyApp(ui, server)
  rval_cluster_merged_df<-reactive({
    
    merge(mockdf(), rval_UserData(), by="randomid")
  #outside of shiny, this would be a quick way to paste the cluster number back onto the mock dataframe
          
  })
  
  
  
  output$clust_dens<-renderPlot({
    
   dd<-rval_cluster_merged_df()
    
      ggplot(dd,aes(x=Duration, colour=Cluster, group=Cluster))+
      geom_density()+ggtitle("Cluster density plot")+scale_x_log10()
    
  })


server<-function(input,output,session){
  
  #create reactive dataframe
  rval_df <-reactive({
    mockdf
  })
   
  #=============================================kmeans clustering==================================================
  rval_UserData<-reactive({
    req(input$userselect)
    userselect <- eval_tidy(input$userselect)
    rval_df()%>%
      filter(randomid %in% userselect)%>%
      group_by(randomid)%>%
      summarise(Count=n(),MeanDuration=mean(Duration),SDDuration=sd(Duration))%>%
      mutate(SDDuration=if_else(is.na(SDDuration),0,SDDuration),
             Cluster=as.factor(rval_kclust()$cluster))
    
  })
  
  #create a scaled dataset for the clustering
  rval_cluster_df<-reactive({
    req(input$userselect)
    userselect <- eval_tidy(input$userselect)
    rval_df()%>%    
      filter(randomid %in% userselect)%>%
      group_by(randomid)%>%
      summarise(Count=n(),MeanDuration=mean(Duration),SDDuration=sd(Duration))%>%
      mutate(SDDuration=if_else(is.na(SDDuration),0,SDDuration),
             Count=scale_this(Count),
             MeanDuration=scale_this(MeanDuration),
             SDDuration=scale_this(SDDuration))%>%
      select(Count,MeanDuration,SDDuration)
    
  }) 
  
  #cluster algorithm
  rval_kclust<-reactive({
    req(input$ksolution)
    centers <- as.numeric(eval_tidy(input$ksolution))
    kmeans(rval_cluster_df(), centers = centers)
  })
  
  output$clustplot<-renderPlot({
    
    factoextra::fviz_cluster(rval_kclust(), data = rval_cluster_df()) 
    
  })
  
  
  output$elbowplot<-renderPlot({
    
    wssplot(rval_cluster_df())
  })
  
  output$Clusterdf<- DT::renderDataTable({
    rval_UserData()
    
  })
  
  rval_cluster_merged_df<-reactive({
    
    merge(rval_df(), rval_UserData(), by="randomid")

  })

  output$clust_dens<-renderPlot({
    
    dd<-rval_cluster_merged_df()
    
    ggplot(dd,aes(x=Duration, colour=Cluster, group=Cluster))+
      geom_density()+ggtitle("Cluster density plot")+scale_x_log10()
    
  })
  
}