dplyr - mutate: columns escaped are false in DT:datatable title edited; was (dplyr - mutate: use dynamic variable names…(used for `DT::datatable`))

我的梦境 提交于 2019-12-24 21:56:43

问题


This tips dplyr - mutate: use dynamic variable names, answer of @Tom Roth works very well, but I have a little issue.

[edit: It seems than dynamic variables are not the cause. Reprex added /edit]

If I change an initial column myCol to an url (for example), and copy the old column myColInitialValue at the end of the dataframe df with a new name, therefore I thought that a which(colnames(df)=='myCol') send back the col # of myColInitialValue but It seems to be an issue in DT::datatable()

My goal is for the escape parameter of DT::datatable(). I use escape=FALSE in waiting that. With constants it doesn't work also but the DT package seems also get the bad # column. :)

Here is my source with the issue of the bad column escaped:

  • the # column is correct
  • when I was debugging I get a dataframe with incorrect order of column but I didn't get again, I didn't reproduce it.
  • but even with the correct number with which() the escaped column displayed in shiny/ datatable is wrong
output$Myoutputdatatable <- DT::renderDataTable( { 
  mydatatable<-Myreactivefunction()
  mydatatable<- ( mydatatable 
                  %>% ungroup() 
                  %>% get_url_pdf(.,nom_colonne_initiale_pour_url = "s_code", 
                                  nom_colonne_code_rempl="s_code_old", 
                                  repertoire_cible = my_path_of_pdf, nom_colonne_test_fichier="s_exists")

                  %>% get_url_pdf(.,nom_colonne_initiale_pour_url = "sp_code", 
                                  nom_colonne_code_rempl="sp_code_old", 
                                  repertoire_cible = my_path_of_pdf, nom_colonne_test_fichier="sp_exists")

  ) 
  escape_vector<-which(colnames(mydatatable) %in% list("s_code","sp_code"))  

  res<-DT::datatable(  mydatatable,
                       style = "bootstrap",   class = "compact", filter='top', 
                       selection = c("single"),
                       escape=escape_vector,
                       options = list(
                         deferRender = TRUE,
                         bSortClasses = TRUE,iDisplayLength = 20,   width = "100%",
                         scrollX=TRUE ,
                         lengthMenu  = list(c(5, 25, 50, 75, 100, -1), list('5', '25','50','75','100', 'All')),                      
                         search = list(
                           smart = TRUE,
                           regex = TRUE, 
                           caseInsensitive = TRUE
                         )                      

                       )
  );

  res <- ( res 
           %>% formatStyle( columns = c("s_code_old"), 
                            valueColumns = c("s_code_old"), target='row', 
                            color = styleEqual(c('__UNKNOWN__'), c("red")) 
           )
  )
  res
} ) 

With my function with the use of the answer of @Tom Roth about dynamic variable in mutate().

get_url_pdf <-function (mydatatable,nom_colonne_initiale_pour_url, nom_colonne_code_rempl, 
                        repertoire_cible,nom_colonne_test_fichier = "" ) {

  # exemple mutate(iris [1:3,], !!("varcible") :=  UQ(rlang::sym("Species") ))


  (mydatatable
   %>% ungroup()
   %>% mutate (
     nom_colonne_test_fichier=nom_colonne_test_fichier,
     varsource =  !!(rlang::sym(nom_colonne_initiale_pour_url) ),
     nom_fichier_pdf=paste0(gsub("\\.", "_",  varsource),'.pdf'),
     var_nom_colonne_test_fichier=ifelse(nom_colonne_test_fichier=='',"",UQ(rlang::sym(nom_colonne_test_fichier))),
     fichier_pdf_existe=ifelse(var_nom_colonne_test_fichier=="",file_test("-f", paste0(repertoire_cible , nom_fichier_pdf)),var_nom_colonne_test_fichier),     
     varcible =  ifelse(fichier_pdf_existe,paste0('<a class="url_pdf" href="http://',hostipserver ,hostportserver,'/rapportpdfpath/',nom_fichier_pdf,'"  target = "_blank">',varsource,'</a>'), varsource)  ,    
     !!(nom_colonne_initiale_pour_url) :=varcible  , 
     !!(nom_colonne_code_rempl) :=varsource         
   )
  )

}

EDIT: REPREX ADDED


library(DT)
library(shiny)
library(dplyr)

hostipserver <- str_trim(system("hostname -I", intern=TRUE))
hostportserver <- ":8080"



app<-
  shinyApp(
    ui = basicPage(
      navbarMenu("Bla",
                 tabPanel("blabla",
                          fluidPage(
                            h3("outblabla_1"),
                            p("toto_1 and toto_2 have to be worked urls but only toto_2 is ok. varcible is a worked url but I don't want it."),
                            fluidRow(
                              column (12,
                                      div(DT::dataTableOutput('outblabla_1'), 
                                          style = "font-size:80%;white-space: nowrap;width:93%")
                              )
                            ),
                            h3("outblabla_2"),
                             p("toto_1 and toto_2 have to be worked urls but only toto_2 is ok"),
                            fluidRow(
                              column (12,
                                      div(DT::dataTableOutput('outblabla_2'), 
                                          style = "font-size:80%;white-space: nowrap;width:93%")
                              )
                            )                            
                          )
                 )
      )           
    ),

    server = function(input, output) {

      blabla <-  reactive({
        test<-data.frame(        
          matrix (rep(c(c(999.2,2), 1200), 4000), nrow = 40, ncol = 30)
        )
        colnames(test) <-  paste0("toto_", 1:30)

        test<-test %>% mutate (toto_9 = ifelse (toto_9==2,TRUE,FALSE))

        return( test)        

      })
      get_url_pdf <-function (mydatatable,nom_colonne_initiale_pour_url, nom_colonne_code_rempl, 
                              repertoire_cible,nom_colonne_test_fichier = "" ) {

        # exemple mutate(iris [1:3,], !!("varcible") :=  UQ(rlang::sym("Species") ))


        (mydatatable
         %>% ungroup()
         %>% mutate (
           nom_colonne_test_fichier=nom_colonne_test_fichier,
           varsource =  !!(rlang::sym(nom_colonne_initiale_pour_url) ),
           nom_fichier_pdf=paste0(gsub("\\.", "_",  varsource),'.pdf'),
           var_nom_colonne_test_fichier=ifelse(nom_colonne_test_fichier=='',"",UQ(rlang::sym(nom_colonne_test_fichier))),
           fichier_pdf_existe=ifelse(var_nom_colonne_test_fichier=="",file_test("-f", paste0(repertoire_cible , nom_fichier_pdf)),var_nom_colonne_test_fichier),     
           varcible =  ifelse(fichier_pdf_existe,paste0('<a class="url_pdf" href="http://',hostipserver ,hostportserver,'/rapportpdfpath/',nom_fichier_pdf,'"  target = "_blank">',varsource,'</a>'), varsource)  ,    
           !!(nom_colonne_initiale_pour_url) :=varcible  , 
           !!(nom_colonne_code_rempl) :=varsource         
         )
        )

      }      

      output$outblabla_1<- DT::renderDataTable( { 
        mydatatable<-blabla()
        mydatatable<- ( mydatatable
                        %>% ungroup()
                        %>% get_url_pdf(.,nom_colonne_initiale_pour_url = "toto_1",
                                        nom_colonne_code_rempl="toto_1_old",
                                        repertoire_cible = my_path_of_pdf, nom_colonne_test_fichier="toto_9"
                        )
                        %>% get_url_pdf(.,nom_colonne_initiale_pour_url = "toto_2",
                                        nom_colonne_code_rempl="toto_2_old",
                                        repertoire_cible = my_path_of_pdf, nom_colonne_test_fichier="toto_9"
                        )                        
        )




        escape_vector<-which(colnames(mydatatable) %in% list("toto_1","toto_2"))  
        print('escape 1' , paste0(escape_vector,(dput(escape_vector))))
        res<-DT::datatable(  mydatatable,
                             style = "bootstrap",   class = "compact", filter='top', 
                             selection = c("single"),
                             escape=escape_vector,
                             options = list(
                               deferRender = TRUE,
                               bSortClasses = TRUE,iDisplayLength = 5,   width = "100%",
                               scrollX=TRUE ,
                               lengthMenu  = list(c(5, 25, 50, 75, 100, -1), list('5', '25','50','75','100', 'All')),                      
                               search = list(
                                 smart = TRUE,
                                 regex = TRUE, 
                                 caseInsensitive = TRUE
                               )                      

                             )
        );
      })

      output$outblabla_2<- DT::renderDataTable( { 
        mydatatable<-blabla()
        mydatatable<- ( mydatatable
                        %>% ungroup()
                        %>% mutate(
                          nom_fichier_pdf_1='a',#paste0(gsub("\\.", "_",  toto_1),'.pdf'),
                          nom_fichier_pdf_2='b',#paste0(gsub("\\.", "_",  toto_2),'.pdf'),

                        toto_1_old=toto_1,
                        toto_1=ifelse(toto_9,paste0('<a class="url_pdf" href="http://',hostipserver ,hostportserver,'/rapportpdfpath/',nom_fichier_pdf_1,'"  target = "_blank">',toto_1,'</a>'), toto_1),
                        toto_2_old=toto_2,
                        toto_2=ifelse(toto_9,paste0('<a class="url_pdf" href="http://',hostipserver ,hostportserver,'/rapportpdfpath/',nom_fichier_pdf_2,'"  target = "_blank">',toto_2,'</a>'), toto_2)                        
                        )


        )




        escape_vector<-which(colnames(mydatatable) %in% list("toto_1","toto_2"))  
        print('escape 2' , paste0(escape_vector,(dput(escape_vector))))
        res<-DT::datatable(  mydatatable,
                             style = "bootstrap",   class = "compact", filter='top', 
                             selection = c("single"),
                             escape=c(1,2),
                             options = list(
                               deferRender = TRUE,
                               bSortClasses = TRUE,iDisplayLength = 5,   width = "100%",
                               scrollX=TRUE ,
                               lengthMenu  = list(c(5, 25, 50, 75, 100, -1), list('5', '25','50','75','100', 'All')),                      
                               search = list(
                                 smart = TRUE,
                                 regex = TRUE, 
                                 caseInsensitive = TRUE
                               )                      

                             )
        );
      })      
    })
shiny::runApp(app)

回答1:


As the answer in rstudio/DT#691, since the rowname is regarded as one column, you should add an additional 1L on the column position. Moreover, since the real intent is to unescape the certain columns, there should be a minus sign on the vector provided.

In short,

escape_vector <- which(colnames(mydatatable) %in% list("toto_1","toto_2")) 

should be changed to

escape_vector <- -( which(colnames(mydatatable) %in% c("toto_1","toto_2")) + 1L ) 


来源:https://stackoverflow.com/questions/57123813/dplyr-mutate-columns-escaped-are-false-in-dtdatatable-title-edited-was-dpl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!