AndriSignorell / DescTools

Tools for Descriptive Statistics and Exploratory Data Analysis
http://andrisignorell.github.io/DescTools/
86 stars 18 forks source link

Desc does not always reset mfrow after creating plots #49

Open ajcullum opened 4 years ago

ajcullum commented 4 years ago

When Desc creates output that show multiple graphs per plot(? Unsure of the terminology), it appears to do this by changing par(mfrow()) and layout(). But those settings are not always returned to the default c(1,1) afterward. The result is that later graphs do not fill the plot area.

The demo code below shows the error. I've seen it occur in other uses of Desc() as well, but this happened before I figured out the issue, and so I didn't make note of the particular arguments that triggered it.

# With default par() values active
db <- structure(list(Group = structure(sample.int(2, 10, replace=T), 
      .Label = c("A", "B"), class = "factor"), 
      Value = sample.int(100, 10, replace=T)), 
      row.names = c(NA, 10L), class = "data.frame")

# This use of Desc() does *not* cause the error
Desc(db$Value~db$Group)  # Gives side-by-side graphs
# Check the layout afterwards
layout.show(2) #  Future graphs will fill the plot area

# This (somewhat unusual) call *does* trigger the error
Desc(db$Group~db$Value)  # Gives side-by-side graphs
# Check the layout afterwards
layout.show(2) # Future graphs will also be in pairs, side-by-side

Thanks!

AndriSignorell commented 4 years ago

This is indeed not a convincing design, which derives from a very early version of DescTools. I will go over that.

GegznaV commented 1 year ago

Here is just a reprex of the code by @ajcullum with outputs and plots:

library(DescTools)

# With default par() values active
db <- structure(list(Group = structure(sample.int(2, 10, replace=T), 
      .Label = c("A", "B"), class = "factor"), 
      Value = sample.int(100, 10, replace=T)), 
      row.names = c(NA, 10L), class = "data.frame")

# This use of Desc() does *not* cause the error
Desc(db$Value~db$Group)  # Gives side-by-side graphs
#> ------------------------------------------------------------------------------ 
#> db$Value ~ db$Group
#> 
#> Summary: 
#> n pairs: 10, valid: 10 (100.0%), missings: 0 (0.0%), groups: 2
#> 
#>                         
#>               A        B
#> mean     44.600   16.000
#> median   59.000   13.000
#> sd       27.682   17.059
#> IQR      37.000   11.000
#> n             5        5
#> np      50.000%  50.000%
#> NAs           0        0
#> 0s            0        0
#> 
#> Kruskal-Wallis rank sum test:
#>   Kruskal-Wallis chi-squared = 3.1527, df = 1, p-value = 0.0758

# Check the layout afterwards
layout.show(2) #  Future graphs will fill the plot area


# This (somewhat unusual) call *does* trigger the error
Desc(db$Group~db$Value)  # Gives side-by-side graphs
#> ------------------------------------------------------------------------------ 
#> db$Group ~ db$Value
#> 
#> Summary: 
#> n pairs: 10, valid: 10 (100.0%), missings: 0 (0.0%), groups: 2
#> 
#>                         
#>               A        B
#> mean     44.600   16.000
#> median   59.000   13.000
#> sd       27.682   17.059
#> IQR      37.000   11.000
#> n             5        5
#> np      50.000%  50.000%
#> NAs           0        0
#> 0s            0        0
#> 
#> Kruskal-Wallis rank sum test:
#>   Kruskal-Wallis chi-squared = 3.1527, df = 1, p-value = 0.0758
#> 
#> 
#> 
#> 
#> 
#> Proportions of db$Group in the quantiles of db$Value:
#>    
#>           Q1       Q2       Q3       Q4
#>   A    33.3%     0.0%    50.0%   100.0%
#>   B    66.7%   100.0%    50.0%     0.0%
#> Warning in par(usr): argument 1 does not name a graphical parameter

# Check the layout afterwards
layout.show(2) # Future graphs will also be in pairs, side-by-side

Created on 2023-02-28 with reprex v2.0.2

GegznaV commented 9 months ago

Is it possible to solve this by using something like on.exit() in an appropriate place?

GegznaV commented 8 months ago

I think the original issue is solved, but some lines of code should be rewritten to make code more robust, eg in these and some other lines of code may need more attention:

https://github.com/AndriSignorell/DescTools/blob/388487e8a3307f734683f1304c38c48332c28190/R/Desc.R#L2832-L2833

https://github.com/AndriSignorell/DescTools/blob/388487e8a3307f734683f1304c38c48332c28190/R/Desc.R#L2936-L2937

https://github.com/AndriSignorell/DescTools/blob/388487e8a3307f734683f1304c38c48332c28190/R/Desc.R#L3099

I recommend resetting via on.exit().