-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Continuous variables will not print from svyCreateTableOne #83
Comments
Hi, it is quite unlikely that installing RTools fixed this issue. RTools is mostly an installer for gcc (C compiler) and gfortran for Windows. MacOS comes with clang (C compiler) so this step is not needed. Also, this package (tableone) does not use C Code, so there is no reason this should be a problem. Since the r-base function
or you could call CreateTableOne with a one column dataframe:
This could help narrow down the problem. Does it affect all continuous columns? |
hi, r-base round function works just fine for my column. and this is specifically for "svyCreateTableOne" rather than "CreateTableOne". there are no issues with the original CreateTableOne. while i can use the svyCreateTableOne function just fine to create the table, an error appears on printing the results if a continuous variable is included. there is no error actually using the svyCreateTableOne function and no error printing if all variables are categorical. so to continue your example: library(tidyverse) tab1_svy <- svydesign(id = ~1, data = pbc, weights = ~wgt) tab1weighted <- svyCreateTableOne(vars = c("copper"), data = tab1_svy) tab1weighted print(tab1weighted) ^ the last 2 lines above will both result in the rounding error while there are no errors for the first 2 lines. |
I recently encountered the same error as @stjeandenise when trying to print the object created by the Based on my amateur sleuthing, I also agree with @ndevln that RTools is probably irrelevant for this particular issue. Reproducible example based on the one from previous posts: ### Load packages
library(tidyverse)
library(tableone)
library(survival)
library(survey)
### Load dataframe
data(pbc)
### Create working copy of dataframe
pbc2 <- pbc
### Generate random weights
set.seed(831)
pbc2$wgt <- rnorm(n = nrow(pbc2), mean = 1, sd = 0.1)
### Create weighted Table 1 object (no errors)
tab1_svy <- svydesign(id = ~1, data = pbc2, weights = ~wgt)
tab1weighted <- svyCreateTableOne(vars = c("copper"), data = tab1_svy)
### Attempt to print weighted Table 1 object (throws an error)
tab1weighted
### Attempt to explicitly print weighted Table 1 object (still throws an error)
print(tab1weighted) Short answer: The error occurs due to how the Long answer: The problem is not that the So why does this happen now when it didn't happen before? My guess is that something changed between when I last ran my code (where it worked without issue) and when I recently re-ran the same code (where I got the error). However, I have found it rather difficult to determine exactly what change caused this to happen. At my job I have access to a couple different instances of R/RStudio, one of which is more locked down (shared server) than the other (local install). In other words, I can quickly check different package versions locally but not on the server (which is where I initially encountered the error). However, I encountered a strange problem when I went to create and run a reproducible example where the error mentioned above is generated: I couldn't get R to generate any errors when printing weighted Table 1 objects. When I ran the reprex above in my local install of R/RStudio, the code worked as expected: tab1weighted
#
# Overall
# n 419.06
# copper (mean (SD)) 97.43 (85.78) No errors, no warnings, and output looks correct. OK, so it must be a version issue, right? R, RStudio, or one or more packages are probably different between the 2 environments where I am running things. (Note that I doubt that RStudio has anything to do with this issue but I'm not ruling it out yet.) Here are my initial local and remote (server) R/RStudio environment versions:
So the reprex works without issue when using ### No package updates -----
library(tidyverse)
library(tableone)
library(survival)
library(survey)
data(pbc)
pbc2 <- pbc
set.seed(831)
pbc2$wgt <- rnorm(n = nrow(pbc2), mean = 1, sd = 0.1)
tab1_svy <- svydesign(id = ~1, data = pbc2, weights = ~wgt)
tab1weighted <- svyCreateTableOne(vars = c("copper"), data = tab1_svy)
tab1weighted
print(tab1weighted)
getRversion(); packageVersion('tableone'); packageVersion('survey')
### R (4.0.3), tableone (0.12.0), survey (4.0)
### RESULT: No errors, everything works as expected.
### Only tableone updated (0.12.0 -> 0.13.0) -----
library(tidyverse)
library(tableone)
library(survival)
library(survey)
data(pbc)
pbc2 <- pbc
set.seed(831)
pbc2$wgt <- rnorm(n = nrow(pbc2), mean = 1, sd = 0.1)
tab1_svy <- svydesign(id = ~1, data = pbc2, weights = ~wgt)
tab1weighted <- svyCreateTableOne(vars = c("copper"), data = tab1_svy)
tab1weighted
print(tab1weighted)
getRversion(); packageVersion('tableone'); packageVersion('survey')
### R (4.0.3), tableone (0.13.0), survey (4.0)
### RESULT: Error message when **creating** `tab1weighted` with the `svyCreateTableOne` function.
### Error in UseMethod("oldsvyquantile", design) :
### no applicable method for 'oldsvyquantile' applied to an object of class "c('survey.design2', 'survey.design')"
### Only survey updated (4.0 -> 4.1-1) -----
library(tidyverse)
library(tableone)
library(survival)
library(survey)
data(pbc)
pbc2 <- pbc
set.seed(831)
pbc2$wgt <- rnorm(n = nrow(pbc2), mean = 1, sd = 0.1)
tab1_svy <- svydesign(id = ~1, data = pbc2, weights = ~wgt)
tab1weighted <- svyCreateTableOne(vars = c("copper"), data = tab1_svy)
tab1weighted
print(tab1weighted)
getRversion(); packageVersion('tableone'); packageVersion('survey')
### R (4.0.3), tableone (0.12.0), survey (4.1-1)
### RESULT: Error message when **printing** `tab1weighted` object.
### Error in round(n, digits = digits) :
### non-numeric argument to mathematical function
### Both tableone (0.12.0 -> 0.13.0) and survey (4.0 -> 4.1-1) updated -----
library(tidyverse)
library(tableone)
library(survival)
library(survey)
data(pbc)
pbc2 <- pbc
set.seed(831)
pbc2$wgt <- rnorm(n = nrow(pbc2), mean = 1, sd = 0.1)
tab1_svy <- svydesign(id = ~1, data = pbc2, weights = ~wgt)
tab1weighted <- svyCreateTableOne(vars = c("copper"), data = tab1_svy)
tab1weighted
print(tab1weighted)
getRversion(); packageVersion('tableone'); packageVersion('survey')
### R (4.0.3), tableone (0.13.0), survey (4.1-1)
### RESULT: No errors, everything works as expected. In short:
...wait. Why did the scenario with I was able to get that exact same error when printing the weighted Table 1 object locally but only when I had updated just the Just to be sure, I loaded the reprex to the remote environment and confirmed that it still generated the error there and the packages available there are definitely still the most recent versions for Windows published to CRAN (at the time of my tests), v. 0.13.0 for So having the latest packages in R v. 4.0.3 didn't result in any errors but having the latest packages in R v. 4.0.5 did? Did something change between 4.0.3 and 4.0.5? Maybe something to do with the According to R News (accessed 2021-09-01), in the "Bug Fixes" section under "CHANGES IN R 4.0.4" there is an item stating:
Unfortunately, due to workplace hyperlink restrictions I am unable to view the referenced pull request so I can't tell if it is likely (or even possible) for this bug fix to have had led to the error that I have been encountering when trying to print weighted Table 1s. The bug fix involving tableone:::print.svyContTable
# ... truncated ...
strataN <- sapply(ContTable, FUN = function(stratum) {
n <- stratum[, "n"]
n[!is.null(n)][1]
n <- ifelse(is.null(n), "0", n)
n <- round(n, digits = digits) ### <-- this line throws the error!
n <- do.call(base::format, c(list(x = n, trim = TRUE),
formatOptions))
as.character(n)
}, simplify = TRUE)
# ... truncated ... When I attempted to step through this code manually (using the round(tab1weighted$ContTable[[1]][, "n"])
# Error in round(tab1weighted$ContTable[[1]][, "n"]) :
# non-numeric argument to mathematical function Finally, I compared the I found that trying to print the "bad" ### "Bad" version
badtab1weighted <- structure(list(Overall = structure(list(419.055217809267, 108.39511607445,
25.8665472872804, 97.433390063506, 85.7825101034694, structure(c(73,
67, 79, 3.04929042994627), .Dim = c(1L, 4L), .Dimnames = list(
"0.5", c("quantile", "ci.2.5", "ci.97.5", "se"))), structure(c(41,
38, 48, 2.54107535828856), .Dim = c(1L, 4L), .Dimnames = list(
"0.25", c("quantile", "ci.2.5", "ci.97.5", "se"))), structure(c(123,
110, 148, 9.65608636149652), .Dim = c(1L, 4L), .Dimnames = list(
"0.75", c("quantile", "ci.2.5", "ci.97.5", "se"))), structure(c(9,
NaN, 12, NaN), .Dim = c(1L, 4L), .Dimnames = list("0", c("quantile",
"ci.2.5", "ci.97.5", "se"))), structure(c(588, 588, 588,
0), .Dim = c(1L, 4L), .Dimnames = list("1", c("quantile",
"ci.2.5", "ci.97.5", "se")))), .Dim = c(1L, 10L), .Dimnames = list(
"copper", c("n", "miss", "p.miss", "mean", "sd", "median",
"p25", "p75", "min", "max")))), class = c("svyContTable",
"ContTable", "by"), percentMissing = c(copper = 25.8373205741627))
print(badtab1weighted)
# Error in round(n, digits = digits) :
# non-numeric argument to mathematical function
### "Good" version
goodtab1weighted <- structure(list(Overall = structure(c(419.055217809267, 108.39511607445,
25.8665472872804, 97.433390063506, 85.7825101034694, 73, 41,
123, 4, 588), .Dim = c(1L, 10L), .Dimnames = list("copper", c("n",
"miss", "p.miss", "mean", "sd", "median", "p25", "p75", "min",
"max")))), class = c("svyContTable", "ContTable", "by"), percentMissing = c(copper = 25.8373205741627))
print(goodtab1weighted)
#
# Overall
# n 419.06
# copper (mean (SD)) 97.43 (85.78) When I compared the structures of the 2 objects, I noticed that the ### "Bad" version
str(badtab1weighted)
# List of 3
# $ ContTable:List of 1
# ..$ Overall:List of 10
# .. ..$ : num 419
# .. ..$ : num 108
# .. ..$ : num 25.9
# .. ..$ : num 97.4
# .. ..$ : num 85.8
# .. ..$ : num [1, 1:4] 73 67 79 3.05
# .. .. ..- attr(*, "dimnames")=List of 2
# .. .. .. ..$ : chr "0.5"
# .. .. .. ..$ : chr [1:4] "quantile" "ci.2.5" "ci.97.5" "se"
# .. ..$ : num [1, 1:4] 41 38 48 2.54
# .. .. ..- attr(*, "dimnames")=List of 2
# .. .. .. ..$ : chr "0.25"
# .. .. .. ..$ : chr [1:4] "quantile" "ci.2.5" "ci.97.5" "se"
# .. ..$ : num [1, 1:4] 123 110 148 9.66
# .. .. ..- attr(*, "dimnames")=List of 2
# .. .. .. ..$ : chr "0.75"
# .. .. .. ..$ : chr [1:4] "quantile" "ci.2.5" "ci.97.5" "se"
# .. ..$ : num [1, 1:4] 9 NaN 12 NaN
# .. .. ..- attr(*, "dimnames")=List of 2
# .. .. .. ..$ : chr "0"
# .. .. .. ..$ : chr [1:4] "quantile" "ci.2.5" "ci.97.5" "se"
# .. ..$ : num [1, 1:4] 588 588 588 0
# .. .. ..- attr(*, "dimnames")=List of 2
# .. .. .. ..$ : chr "1"
# .. .. .. ..$ : chr [1:4] "quantile" "ci.2.5" "ci.97.5" "se"
# .. ..- attr(*, "dim")= int [1:2] 1 10
# .. ..- attr(*, "dimnames")=List of 2
# .. .. ..$ : chr "copper"
# .. .. ..$ : chr [1:10] "n" "miss" "p.miss" "mean" ...
# ..- attr(*, "class")= chr [1:3] "svyContTable" "ContTable" "by"
# ..- attr(*, "percentMissing")= Named num 25.8
# .. ..- attr(*, "names")= chr "copper"
# $ CatTable : NULL
# $ MetaData :List of 6
# ..$ vars : chr "copper"
# ..$ logiFactors : logi FALSE
# ..$ varFactors : chr(0)
# ..$ varNumerics : chr "copper"
# ..$ percentMissing: Named num 25.8
# .. ..- attr(*, "names")= chr "copper"
# ..$ varLabels :List of 1
# .. ..$ copper: NULL
# - attr(*, "class")= chr [1:2] "svyTableOne" "TableOne"
### "Good" version
str(goodtab1weighted)
# List of 3
# $ ContTable:List of 1
# ..$ Overall: num [1, 1:10] 419.1 108.4 25.9 97.4 85.8 ...
# .. ..- attr(*, "dimnames")=List of 2
# .. .. ..$ : chr "copper"
# .. .. ..$ : chr [1:10] "n" "miss" "p.miss" "mean" ...
# ..- attr(*, "class")= chr [1:3] "svyContTable" "ContTable" "by"
# ..- attr(*, "percentMissing")= Named num 25.8
# .. ..- attr(*, "names")= chr "copper"
# $ CatTable : NULL
# $ MetaData :List of 6
# ..$ vars : chr "copper"
# ..$ logiFactors : logi FALSE
# ..$ varFactors : chr(0)
# ..$ varNumerics : chr "copper"
# ..$ percentMissing: Named num 25.8
# .. ..- attr(*, "names")= chr "copper"
# ..$ varLabels :List of 1
# .. ..$ copper: NULL
# - attr(*, "class")= chr [1:2] "svyTableOne" "TableOne" As you can see, the ### "Bad" version
badtab1weighted$ContTable[[1]][, "n"]
# [[1]]
# [1] 419.0552
### "Good" version
goodtab1weighted$ContTable[[1]][, "n"]
# [1] 419.0552 The "bad" object produces a list of length 1 containing a vector of length 1 whereas the "good" object just produces the vector of length 1. The 2 numeric values are identical but the structures containing them are not. As a result, when you pass these results to the ### "Bad" version
round(badtab1weighted$ContTable[[1]][, "n"])
# Error in round(badtab1weighted$ContTable[[1]][, "n"]) :
# non-numeric argument to mathematical function
### Fixed "bad" version (note the additional `[[1]]` at the end)
round(badtab1weighted$ContTable[[1]][, "n"][[1]])
# [1] 419
### "Good" version
round(goodtab1weighted$ContTable[[1]][, "n"])
# [1] 419 Sadly, that is where my investigation ends. I don't have enough knowledge to suggest a fix for this issue. Even worse, I have absolutely no idea why running the same code in 2 different R sessions both using the same (latest) versions of the Was it because of the different R versions (v. 4.0.3 vs v. 4.0.5)? Was it because the R sessions were running under different operating systems (Windows 10 (64-bit) vs Windows 2012 Server R2 (64-bit))? Was it because of something to do with R v. 4.0.3 running packages that were compiled under R v. 4.0.5? Was it because of the bug fix made to the Hopefully a more knowledgeable person will be able to address this issue. And who knows? Maybe it's not even an issue in R v. 4.1.0 and later. |
Thanks for the very detailed explanations above. Extremely helpful. It appears that the survey package (v 4.1-1) changed the output for quantiles (object class "newsvyquantile"). The tableone package does not work with this new output format. The function oldsvyquantile gives the output in the older format. As an interim fix, the following lines of code should work svyQuant_alt <- function (vars, design, q = 0.5) { environment(svyQuant_alt) <- asNamespace('tableone') |
thanks so much for the workaround, @docvock!! |
Thank you both for all of this! |
Thank you so much! I just ran into this issue today (while I was teaching a class with this code) and thought I had made some terrible error (other than not triple checking before classtime...). |
Categorical variable work fine but any attempt to print continuous variables yields the following error:
Error in round(n, digits = digits) : non-numeric argument to mathematical function
Someone reported the same exact issue on Stack Overflow this week and was able to fix it using RTools. However, RTools is specific to Windows and I am a Mac user so I do not know how to proceed. Is there a bug on the developer end causing this issue?
The text was updated successfully, but these errors were encountered: