2017-10-16 111 views
1

我正在使用R和EBImage包編程一個用於圖像分析的閃亮應用程序。 經過一些困難,我有一些不錯的成績,但在時間繪製computeFeatures的結果,我有一些奇怪的行爲:DataTableOutput中的混沌順序和多幀圖像中的奇怪computeFeature圖

  • 我不得不明令「細胞」欄才能正常目前datatableoutput數據。
  • 圖形具有「幀」因子的倒序。
  • 分佈圖顯示幀不共享圖像的通用像素尺寸。看到幀之間沒有座標x和座標y的重疊。這意味着像框架不在同一個位置。

下面是一個例子:

library(EBImage) 
library(shiny) 
library(tidyverse) 
library(DT) 

ui <- basicPage(
    column(
    width = 3, 
    h3("Images"), 
    displayOutput("nuc"), 
    displayOutput("nucbw") 
    ), 
    column(
    width = 9, 
    h3("Cell Features"), 
    DT::dataTableOutput("basicfeatures"), 
    hr(), 
    fluidRow(
     column(
     width = 4, 
     plotOutput("plot1") 
     ), 
     column(
     width = 8, 
     plotOutput("plot2") 
     ) 
    ) 
    ) 
) 

server <- function(input, output) { 

    # Load Image 
    nuc <- readImage(system.file("images", "nuclei.tif", package="EBImage")) 
    # Segmented Image 
    nucbw <- bwlabel(nuc > 0.5) 

    # Display Original Image 
    output$nuc <- renderDisplay(display(nuc)) 

    # Display Segmented Image 
    output$nucbw <- renderDisplay(display(nucbw)) 

    # Compute Features 
    features <- reactive({ 
    # Create empty dataframe 
    data <- data.frame() 
    # Obect to save total cell number 
    ntotal <- 0L 
    # Compute for each frame 
    for (i in 1:numberOfFrames(nuc)){ 
     nobjects <- max(nucbw[,,i]) 
     cell <- seq.int(from = ntotal + 1L, length.out = nobjects) 
     ntotal <- ntotal + nobjects 
     # Create frame column to know the frame where each cell belongs 
     frame <- rep(paste("Frame", i, sep = " "), nobjects) 
     # Create features dataframe 
     x1 <- computeFeatures.basic(nucbw[,,i], nuc[,,i]) 
     x2 <- computeFeatures.shape(nucbw[,,i], nuc[,,i]) 
     x3 <- computeFeatures.moment(nucbw[,,i], nuc[,,i]) 
     # Binding dataframe for each frame 
     bind <- cbind(cell, frame, x1, x2, x3) 
     # Binding dataframe different frame 
     data <- rbind(bind, data) 
    } 

# Convert "cell" to numeric 
    cell <- as.numeric(as.character(data$cell)) 
# "frame" remains untouched 
    frame <- data$frame 
# Convert computeFeatures to numeric 
    temp <- as.data.frame(data.matrix(data[,-c(1,2)])) 
# Binding to a unique data frame 
    data <- cbind(cell, frame, temp) 

    data 
    }) 


    # Render Features Table 
    output$basicfeatures <- DT::renderDataTable(
    features(), 
    rownames = FALSE, 
    caption = "Cell Features", 
    extensions = list(
     "ColReorder" = NULL, 
     "FixedHeader" = NULL 
    ), 
    options = list(
     pageLength = 10, 
     colReorder = TRUE, 
     fixedHeader = TRUE, 
     scrollX = TRUE, 
     order = list(0, 'asc') 
    ) 
    ) 

    data2 <- reactive({ 
    features() %>% 
     group_by(frame) %>% 
     summarise(n = n()) 
    }) 

    output$plot1<- renderPlot({ 
    g <- ggplot(data2(), aes(x = frame, y = n)) + 
     geom_col(aes(fill = frame), color = "black") + 
     labs(title = "NUMBER OF CELLS PER FRAME", x = "FRAME", y = "NUMBER OF CELLS") + 
     theme_bw(base_size = 16) + 
     theme(legend.position = "none") + 
     theme(axis.text = element_text(size = 14)) 
    g 
    }) 

    output$plot2<- renderPlot({ 
    g <- ggplot(features(), aes(x = m.cx, y = m.cy, fill = frame, color = frame)) + 
     geom_point(shape = 21, size = 4, alpha = 0.2) + 
     labs(title = "DISTRIBUTION OF CELLS", x = "COORDINATE X", y = "COORDINATE Y") + 
     theme_bw(base_size = 16) + 
     theme(
     rect = element_rect(colour = "red"), 
     strip.background = element_rect(colour = "black", fill = "white"), 
     strip.text.x = element_text(colour = "black"), 
     strip.text.y = element_text(colour = "black") 
     ) + 
     facet_wrap(~ frame, nrow = 1) 
    g 
    }) 

} 

shinyApp(ui, server) 
+0

執行'data < - rbind(data,bind)'而不是'data < - rbind(bind,data)'應該可以解決與訂單相關的問題。 – SBista

+0

你說得對。它解決了我的問題的前兩點。謝謝 – Archymedes

回答

0

的問題是由您的中間字符數據表示使用因子存儲的事實引起的,並且該呼叫到data.matrix可以通過內部碼替換因素,而不是他們代表的數字。最簡單的方法是在library調用後設置options(stringsAsFactors = FALSE)

但是,您應該避免首先轉換爲字符。當數字特徵矩陣x1,x2,是cbindframe字符向量時,會發生此強制。發生這種情況是因爲character是這些不同數據類型的共同點。但是,您可以通過在此處創建data.frame來避免此問題:bind <- data.frame(cell, frame, x1, x2, x3)。然後在for循環之後的所有數據轉換步驟都不再需要了。

+0

完美,它工作正常,但只是一個細節:繪製「分佈圖」時,我仍然需要將「m.cx」和「m.cy」轉換爲數字變量,以正確繪製爲連續變量。謝謝你的幫助。我看到你正在開發EBImage和RBioFormats軟件包,這真是太棒了,祝賀你。我用它們很多。 – Archymedes

+0

對,如果你決定去選擇'stringsAsFactors = FALSE',你仍然需要這樣做。然而,正如我所指出的那樣,這是對後者的一種較差的解決方案,它不包括對「人物」的強制。您應該避免任何不必要的數據轉換,特別是在Shiny應用程序的代碼中,因爲這會影響應用程序的響應性。如果我的答案解決了您的問題,您可以考慮接受和/或對其進行投票。 – aoles

+0

感謝您的建議。我沒有正確地將「綁定< - data.frame(cell,frame,x1,x2,x3)」data.frame包含到循環中。它必須位於「bind < - cbind(cell,frame,x1,x2,x3)」之後。非常感謝 – Archymedes