Как динамически объединять столбцы загрузок XLSX из приложения R Shiny с помощью пакета xlsx? - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь динамически объединять столбцы загрузок XLSX из приложения R Shiny с помощью пакета xlsx.В настоящее время я могу объединить столбцы документа XLSX, созданного из статического фрейма данных, как показано в следующем минимальном примере:

library(xlsx)

# Creating dataframe.
df <- data.frame(c("Title", 1, "one"),
                 c("", 2, "two"),
                 c("", 3, "three"))

# Creating a workbook using the XLSX package.
wb <- xlsx::createWorkbook(type = "xlsx")

# Creating a sheet inside the workbook.
sheet <- xlsx::createSheet(wb, sheetName = "Sheet0")

# Adding the full dataset into the sheet.
xlsx::addDataFrame(df, sheet, startRow = 1, startCol = 1, row.names = FALSE, col.names = FALSE)

# Merging first three columns.
addMergedRegion(sheet, 1, 1, 1, 3)

# Saving the workbook.
xlsx::saveWorkbook(wb, "df.xlsx")

Я реализовал логику этого примера в следующем приложении R Shiny:

# ui.R

fluidPage(
  h1("Download XLSX"),
  downloadButton("download.button", label = "Download")
)

# server.R

library(xlsx)

function(input, output) {

  # Creating dataframe.
  df <- data.frame(c("Title", 1, "one"),
                   c("", 2, "two"),
                   c("", 3, "three"))

  # Handling download.
  # Creating XLSX file for download.
  output$download.button <- downloadHandler(
    filename <- paste0("df.xlsx"),
    content <- function(file) {
      # Creating a workbook using the XLSX package.
      wb <- xlsx::createWorkbook(type = "xlsx")

      # Creating a sheet inside the workbook.
      sheet <- xlsx::createSheet(wb, sheetName = "Sheet0")

      # Adding the full dataset into the sheet.
      xlsx::addDataFrame(df, sheet, startRow = 1, startCol = 1, row.names = FALSE, col.names = FALSE)

      # Merging first three columns.
      addMergedRegion(sheet, 1, 1, 1, 3)

      # Saving the workbook.
      xlsx::saveWorkbook(wb, file)
    }
  )

}

В приведенном выше примере addMergedRegion(sheet, 1, 1, 1, 3) объединяет первые три столбца первой строки в один.Я хотел бы иметь возможность делать это динамически, а не с помощью жесткого кодирования, потому что я буду работать с кадрами данных разных размеров.В качестве входных данных я хочу использовать список индексов строк, индексов столбцов и диапазонов столбцов.Это будут все значения, которые мне нужны для заполнения функции addMergedRegion(), однако я не уверен, как динамически генерировать функции, необходимые для объединения столбцов.В качестве одного из примеров этой проблемы я создал это второе приложение:

# ui.R

fluidPage(
  h1("Download XLSX"),
  numericInput("numeric.input", "Select Number of Tables:", 1, min = 1),
  DT::dataTableOutput("table"),
  downloadButton("download.button", label = "Download")
)

# server.R

library(DT)
library(xlsx)

function(input, output) {

  # Creating dataframe.
  df <- data.frame(c("Title", 1, "one"),
                   c("", 2, "two"),
                   c("", 3, "three"))

  # Creating reactive dataframe.
  values <- reactiveValues(
    df = df
  )

  # Expanding dataframe based on user input.
  observeEvent(input$numeric.input, {
    values$df <- df[rep(seq_len(nrow(df)), input$numeric.input), ]
  })

  # Rendering data table of dataframe.
  output$table <- DT::renderDataTable({
    DT::datatable(values$df,
                  selection = "none",
                  rownames = FALSE,
                  options = list(dom = "t",
                                 ordering = FALSE,
                                 pageLength = nrow(values$df)))
  })

  # Handling download.
  # Creating XLSX file for download.
  output$download.button <- downloadHandler(
    filename <- paste0("df.xlsx"),
    content <- function(file) {
      # Creating a workbook using the XLSX package.
      wb <- xlsx::createWorkbook(type = "xlsx")

      # Creating a sheet inside the workbook.
      sheet <- xlsx::createSheet(wb, sheetName = "Sheet0")

      # Adding the full dataset into the sheet.
      xlsx::addDataFrame(values$df, sheet, startRow = 1, startCol = 1, row.names = FALSE, col.names = FALSE)

      # Saving the workbook.
      xlsx::saveWorkbook(wb, file)
    }
  )

}

Это приложение расширяет строки данных на основе пользовательского ввода.Как дать каждой ячейке, содержащей строку «Заголовок», интервал столбца 3 в динамическом регистре, таком как этот?

1 Ответ

0 голосов
/ 25 апреля 2018

Я не могу использовать xlsx из-за проблем с Java, но я думаю, все, что вам нужно, это:

indices <- which(df=="Title", arr.ind=TRUE)

Это даст вам матрицу индексов строк и столбцов n x 2, которую вы затем сможете использовать в addMergedRegion:

apply(indices, 1, function (x) {
  xlsx::addMergedRegion(sheet, x[1], x[1], x[2], x[2] + 2)
})

Жизнь будет немного сложнее, если вы хотите, чтобы ячейки, которые содержали"Заголовок", а не ячейки, которые равны"Заголовок":

x <- matrix(NA, nrow(df), ncol(df))
x[] <- grepl("Title", unlist(df))
indices <- which(x, arr.ind = TRUE)

... и продолжайте как прежде.

...