pwr icon indicating copy to clipboard operation
pwr copied to clipboard

Analysis for a vector of values fails

Open mattansb opened this issue 4 years ago • 2 comments

I'm trying to compute a power curve, and came across this rather off behavior - when providing d as a vector, the function fails, but supplying each element of d separately does not:

library(pwr)

d <- seq(0.05, 1.2, length.out = 25)
pwr.t.test(d = d, power = 0.8)$n
#> Warning in if (is.na(f.lower)) stop("f.lower = f(lower) is NA"): the condition
#> has length > 1 and only the first element will be used
#> Warning in if (is.na(f.upper)) stop("f.upper = f(upper) is NA"): the condition
#> has length > 1 and only the first element will be used
#> Error in uniroot(function(n) eval(p.body) - power, c(2 + 1e-10, 1e+09)): f() values at end points not of opposite sign

sapply(d, function(.d) pwr.t.test(d = .d, power = 0.8)$n)
#>  [1] 6280.04894 1638.24246  739.07484  419.13283  269.74754  188.15814
#>  [7]  138.77956  106.64471   84.56849   68.75267   57.03626   48.11621
#> [13]   41.16893   35.65311   31.20120   27.55646   24.53518   22.00310
#> [19]   19.86028   18.03104   16.45725   15.09369   13.90466   12.86180
#> [25]   11.94226

Created on 2020-11-22 by the reprex package (v0.3.0)

mattansb avatar Nov 22 '20 15:11 mattansb

Thanks for your comment. As you say, the functions of the package are meant to return a single result. That's the clearest API, since there are many possible parameters that might be varied, so for instance: what output would you expect if you want to test different effect sizes, power values, etc.?

Using sapply or a loop, as you present, is the way to go if you want multiple outputs. You can also use plot to see the relationship of sample size and test power.

heliosdrm avatar Dec 16 '20 16:12 heliosdrm

the functions of the package are meant to return a single result

I can't seem to recreate it now, but I remember previously getting multiple results when passing a vector to a pwr.* function. But maybe it was just a dream 😅

I think it could be really useful to allow one of the inputs to be a vector, which in turn would result in an output where the argument that was left as NULL would be a corresponding vector.

e.g.:

pwr.t.test(d = 0.3, power = c(0.8, 0.9))
#> 
#>      Two-sample t test power calculation 
#> 
#>               n = 175.3847, 234.4627
#>               d = 0.3
#>       sig.level = 0.05
#>           power = 0.8, 0.9
#>     alternative = two.sided
#> 
#> NOTE: n is number in *each* group

mattansb avatar Dec 17 '20 09:12 mattansb