如何阻止 lapply 和 formatC 函数处理数据 table 中的 NULL 值?

How to stop lapply and formatC functions from processing NULL values in data table?

我正在尝试解决格式错误。我使用 lapply() 对数据框应用的 formatC() 函数正在向数据框输出列 header 中的 NULL 值添加一个小数点。我确实想让 NULL 值出现在我的输出列 header 中,我只是不想要一个“。”添加到列 header 中每个 NULL 输出的末尾。 lapply()formatC() 的组合对于格式化数据框中的数值很重要(尽管为了简洁起见,在下面的可重现代码中它们没有生成)。请查看底部的图片,您可以在其中看到问题。

我已经尝试遵循 的建议,但它对我来说还没有奏效。

那么如何防止“重叠”formatC() 到 NULL 元素?不要管 NULL。

下面是 seriously-gutted 代码,它在 # commenting-out the below line removes the "." from the NULL 行(其他 2 commented-out 行是我试图解决的)下面的一行中显示有问题的代码并生成图中显示的输出,仅说明手头的问题:

library(data.table)
library(dplyr)
library(DT)
library(shiny)
library(tidyverse)

transitDF <- 
  as.data.frame(
    data.table(
      ID = as.numeric(c("1930145","1930145","1930145","1930145","1930145")),
      Period_1 = as.numeric(c("1","2","3","4","5")),
      Period_2 = c("2012-10","2012-11","2012-12","2013-01","2013-02"),
      Values = as.numeric(c("8","17.97","97.85","87.85","273.85")),
      State = c("NULL","NULL","NULL","NULL","NULL")
    )
  )  

num_transit <- function(x,from,to,refvar="Period_2", return_matrix=T) {
  res <- x[get(refvar) %in% c(to,from), if(.N>1) .SD, by=ID, .SDcols = c(refvar, "State")]
  res <- res[, id:=1:.N, by=ID]
  res <- dcast(res, ID~id, value.var="State")[,.N, .(`1`,`2`)]
  setnames(res,c("from","to", "ct"))
  if(return_matrix) return(convert_transits_to_matrix(res, unique(x$State)))
  res
}

convert_transits_to_matrix <- function(transits,states) {
  m = matrix(NA, nrow=length(states), ncol=length(states), dimnames=list(states,states))
  m[as.matrix(transits[,.(to,from)])] <- transits[[3]] 
  m = data.table(m)[,to_state:=rownames(m)]
  setcolorder(m,"to_state")
  return(m[])
}

ui <- fluidPage(DTOutput("resultstransitDF"))

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

  results <- 
    reactive({
      setDT(transitDF)
      results <- num_transit(transitDF,1,2,"Period_1")
      results <- cbind(results, Sum = rowSums(results[,-1])) 
    
    # commenting-out the below line removes the "." from the NULL
      results[] <- as.data.frame(lapply(results, formatC, decimal.mark ="."))
      
    # results[] <- as.data.frame(lapply(results, function(x) if (!is.null(x)) (formatC, decimal.mark =".") else NULL))
    # results[] <- as.data.frame(lapply(if(!is.null(results)), formatC, decimal.mark ="."))
            
    })
  
  output$resultstransitDF <- renderDT(server=FALSE, {datatable(data = results())})
  
}

shinyApp(ui, server)

当运行以上时输出:

抱歉我的评论,我不明白这个问题。事实上,这与 formatC 无关,后者无论如何都不适用于列名。问题在于使用 "NULL" 作为列表组件的名称,并且 as.data.frame 默认“更正”此名称。

> m <- matrix(1, nrow=1, ncol=1, dimnames=list("NULL", "NULL"))
> m # ok
     NULL
NULL    1
> data.table(m) # ok
   NULL
1:    1
> as.data.frame(data.table(m)) # ok
  NULL
1    1
> as.data.frame(lapply(data.table(m), formatC)) # not ok
  NULL.
1     1
> data.frame("NULL" = 4) # the problem is here: the "NULL" string is reserved
  NULL.
1     4
> lapply(data.table(m), formatC) # look, the name is the NULL object, not the "NULL" string
$`NULL`
[1] "1"
> # you can solve the problem as follows:
> as.data.frame(lapply(data.table(m), formatC), check.names = FALSE)
  NULL
1    1