managing decimal values for output summary

sample data

dataa<-data.frame(
  aa = c("q","r","y","v","g","y","d","s","n","k","y","d","s","t","n","u","l","h","x","c","q","r","y","v","g","y","d","s","n","k","y","d","s","t","n","u","l","h","x","c"),
col1=c(1,2,3,2,1,2,3,4,4,4,5,3,4,2,1,2,5,3,2,1,2,4,2,1,3,2,1,2,3,1,2,3,4,4,4,1,2,5,3,5),
col2=c(2,1,1,7,4,1,2,7,5,7,2,6,2,2,6,3,4,3,2,5,7,5,6,4,4,6,5,6,4,1,7,7,2,7,7,2,3,7,2,4)
)

I have written the function below, which is working fine, but I need to make two amendments

  1. All values should show decimal values 0.0 or 22.0 (right now if value is 22.0 its showing as 22) except for Total sum
  2. if a values in summary is 0.0 or 0 it should be visible as "--" (for total i have already added a condition)
tab_std_cross <- function(dat1,var1,grouping_var){
  
  var1 <- rlang::parse_expr(var1)
  var2 <- rlang::parse_expr(grouping_var)
  
  dat2 <- dat1 %>% select(!!var1,!!var2)
  var_lab(dat2[[1]]) <- ""
  var_lab(dat2[[2]]) <- ""
  tab1 <- expss::cro_cpct(dat2[[1]],dat2[[2]]) # this will create a crosstab summary
  tab1 <- as.data.frame(tab1)
  tab1[which(tab1[,1]=="#Total cases"),1] <- "N"
  tab1[is.na(tab1)] <- 0
  tab1 <- tab1 %>%
    mutate(
      across(
        .cols = where(is.numeric),
        .fns = ~ round(.x, digits = 1)
      )
    )
  mask_indices <- sapply(tab1, function(x) x[length(x)] %in% c(3, 4, 5)) %>%
    which()  # if sum of total falls in (3,4,5) the the whole column will replace as "--"
  tab1[, mask_indices] <- "--"
  tab1[-nrow(tab1), -mask_indices] <- sapply(tab1[-nrow(tab1), -mask_indices], function(x) paste(x, "%"))
  tab1[tab1=="0.0"] <- "--"
  tab1 <- flextable(tab1)
  tab1
}

i have trued using Format( round(.x, digits = 1),nsmall=1) but after using that my afterward conditions are not working.

the output coming from this function is like

the output i want like below

Hello,

The function you'd like to use here is sprintf()

values  = c(0, 2.3333, 2)
ifelse(values == 0,"--", sprintf("%.2f %%", values))
#> [1] "--"     "2.33 %" "2.00 %"

Created on 2020-08-12 by the reprex package (v0.3.0)

You can write a string and substitute parts with formatted variables. In this case, %f means substitute a float value, and %.2f means round to two decimal places (even if whole number). The double %% means output an actual percent sign.

For more info, read about other sprintf substitutions like %s for strings.

Hope this helps,
PJ

hi i have managed to do below

tab_std_cross <- function(dat1,var1,grouping_var){
  
  var1 <- parse_expr(var1)
  var2 <- parse_expr(grouping_var)
  
  dat2 <- dat1 %>% select(!!var1,!!var2)
  var_lab(dat2[[1]]) <- ""
  var_lab(dat2[[2]]) <- ""
  tab1 <- cro_cpct(dat2[[1]],dat2[[2]]) 
  tab1 <- as.data.frame(tab1)
  tab1[which(tab1[,1]=="#Total cases"),1] <- "N"
  tab1[is.na(tab1)] <- 0
  tab1 <- tab1 %>%
    mutate(
      across(
        .cols = where(is.numeric),
        .fns = ~ round(.x, digits = 1)
      )
    )
  tab1[tab1 == 0] <- '--' # --- (1)
  mask_indices <- sapply(tab1, function(x) x[length(x)] %in% c(3, 4, 5)) %>%
    which()  
  tab1[, mask_indices] <- "--"
  tab1[-nrow(tab1), -c(1, mask_indices)] <- sapply(
      tab1[-nrow(tab1),-c(1, mask_indices)], function(x) # --- (2)
    ifelse(x != '--', paste(format(as.numeric(x), nsmall = 1), "%"), x)) # --- (3)
  tab1 <- flextable(tab1)
  tab1
}

but still some of the columns are showing five decimal values

hi i have managed to do below

tab_std_cross <- function(dat1,var1,grouping_var){
  
  var1 <- parse_expr(var1)
  var2 <- parse_expr(grouping_var)
  
  dat2 <- dat1 %>% select(!!var1,!!var2)
  var_lab(dat2[[1]]) <- ""
  var_lab(dat2[[2]]) <- ""
  tab1 <- cro_cpct(dat2[[1]],dat2[[2]]) 
  tab1 <- as.data.frame(tab1)
  tab1[which(tab1[,1]=="#Total cases"),1] <- "N"
  tab1[is.na(tab1)] <- 0
  tab1 <- tab1 %>%
    mutate(
      across(
        .cols = where(is.numeric),
        .fns = ~ round(.x, digits = 1)
      )
    )
  tab1[tab1 == 0] <- '--' # --- (1)
  mask_indices <- sapply(tab1, function(x) x[length(x)] %in% c(3, 4, 5)) %>%
    which()  
  tab1[, mask_indices] <- "--"
  tab1[-nrow(tab1), -c(1, mask_indices)] <- sapply(
      tab1[-nrow(tab1),-c(1, mask_indices)], function(x) # --- (2)
    ifelse(x != '--', paste(format(as.numeric(x), nsmall = 1), "%"), x)) # --- (3)
  tab1 <- flextable(tab1)
  tab1
}

but still some of the columns are showing five decimal values , do you have any solution or updation for this

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.