dims [product xx] do not match the length of object [xx] error in using R function `outer`
I often explain outer(x, y, FUN)
when both x
and y
are vectors with the following:
xx <- rep(x, times = length(y))
yy <- rep(y, each = length(x))
zz <- FUN(xx, yy)
stopifnot(length(zz) == length(x) * length(y)) ## length = product?
z <- matrix(zz, length(x), length(y))
funError
fails because zz
has length 1, while funNoError
does not because "recycling rule" has been applied when you paste a
(a vector with length > 1) and class(a)
(a length-1 vector).
This is illustrative as you will see why outer(1:5, 1:5, "+")
works but outer(1:5, 1:5, sum)
fails. Basically, FUN
must be able to process xx
and yy
element-wise. Otherwise, wrap FUN
with a sugar function called Vectorize
. More details are given later.
Note that "list" is also a valid mode of a vector. So outer
could be used to some non-standard things like How to perform pairwise operation like `%in%` and set operations for a list of vectors.
You can pass matrices / arrays to outer
, too. Given that they are just vectors with an "dim" attribute (optionally with "dimnames"), how outer
works does not change.
x <- matrix(1:4, 2, 2) ## has "dim"
y <- matrix(1:9, 3, 3) ## has "dim"
xx <- rep(x, times = length(y)) ## xx <- rep(c(x), times = length(y))
yy <- rep(y, each = length(x)) ## yy <- rep(c(y), each = length(x))
zz <- "*"(xx, yy)
stopifnot(length(zz) == length(x) * length(y)) ## length = product?
z <- "dim<-"( zz, c(dim(x), dim(y)) )
z0 <- outer(x, y, "*")
all.equal(z, z0)
#[1] TRUE
?outer
explains the code above in plain words.
‘X’ and ‘Y’ must be suitable arguments for ‘FUN’. Each will be
extended by ‘rep’ to length the products of the lengths of ‘X’ and
‘Y’ before ‘FUN’ is called.
‘FUN’ is called with these two extended vectors as arguments (plus
any arguments in ‘...’). It must be a vectorized function (or the
name of one) expecting at least two arguments and returning a
value with the same length as the first (and the second).
Where they exist, the [dim]names of ‘X’ and ‘Y’ will be copied to
the answer, and a dimension assigned which is the concatenation of
the dimensions of ‘X’ and ‘Y’ (or lengths if dimensions do not
exist).
The word "vectorized" is NOT the most discussed one in R on performance. It means "vectorizing the action of a function":
## for FUN with a single argument
FUN( c(x1, x2, x3, x4) ) = c( FUN(x1), FUN(x2), FUN(x3), FUN(x4) )
## for FUN with two arguments
FUN( c(x1, x2, x3, x4), c(y1, y2, y3, y4) )
= c( FUN(x1, y1), FUN(x2, y2), FUN(x3, y3), FUN(x4, y4) )
Some functions say "+"
, "*"
, paste
behave like this, but many others don't, say class
, sum
, prod
. The *apply
family functions in R are there to help you to vectorize function action, or you can write your own loop to achieve the same effect.
Another worth reading good-quality Q & A: Why doesn't outer work the way I think it should (in R)?
R - cross validation error handling-- dims product do not match the length of object
If you want to "fix" this you will need to pull out the attributes of the pred
object and then select matching values from the Hitters
object based on its rownames()
.
> str(Hitters$Salary)
num [1:322] NA 475 480 500 91.5 750 70 100 75 1100 ...
> str(pred)
num [1:18, 1] 988 359 370 808 383 ...
- attr(*, "dimnames")=List of 2
..$ : chr [1:18] "-Andre Thornton" "-Bob Dernier" "-Chris Brown" "-Chet Lemon" ...
..$ : NULL
> names(Hitters)
[1] "AtBat" "Hits" "HmRun" "Runs" "RBI" "Walks" "Years" "CAtBat"
[9] "CHits" "CHmRun" "CRuns" "CRBI" "CWalks" "League" "Division" "PutOuts"
[17] "Assists" "Errors" "Salary" "NewLeague"
> rownames(Hitters)
[1] "-Andy Allanson" "-Alan Ashby" "-Alvin Davis" "-Andre Dawson"
[5] "-Andres Galarraga" "-Alfredo Griffin" "-Al Newman" "-Argenis Salazar"
[9] "-Andres Thomas" "-Andre Thornton" "-Alan Trammell" "-Alex Trevino"
[13] "-Andy VanSlyke" "-Alan Wiggins" "-Bill Almon" "-Billy Beane"
#omitted the rest of the 322-item column
R reshape package: Error in Dim(x)... dims [product 100] do not match the length of object [109]
I don't know what's causing the error, but here is how you should fix it:
- Use
reshape2
- this is an updated version which is also faster. - Use
dcast
- the cast function in reshape2 which explicitly returns a data.frame, as opposed toacast
that returns an array.
The code:
library(reshape2)
castDf <- dcast( meltDf , DATE + CITY ~ variable)
castDf
The results:
DATE CITY DAILY_MAX_TEMP
1 1953-01-01 Anqing 9.1
2 1953-01-02 Anqing 5.1
3 1953-01-03 Anqing 5.2
4 1953-01-04 Anqing 4.6
5 1953-01-05 Anqing 7.9
6 1953-01-06 Anqing 9.9
dplyr, dunn test, Error in dim(robj) - c(dX, dY) : dims [product 0] do not match the length of object
First of all %>%
pipe passes a data.frame to the pairw.kw
function as a first argument. Secondly, pairw.kw
function wants two vectors as an input. You can achive this with %$%
pipe from magrittr
package. It works similar to with
function.
library(magrittr)
example.df %>%
filter(treated=="No") %$%
pairw.kw(var1, species, conf = 0.95)
Answer to question in comment:
library(tidyverse)
library(magrittr)
library(asbio)
example.df %>%
group_by(treated) %>%
nest() %>%
mutate(
kw = map(
data,
~ .x %$% pairw.kw(var1, species, conf = 0.95)
),
p_val = map_dbl(kw, ~ .x$summary$`Adj. P-value`)
)
R: Use outer() on user-defined function
To use outer
, some basic "requirements":
the function will take two vectors all at once (as shown below); whether it chooses to do vectorized work on them or work on them individually is up to you;
it must return a vector of the same length as
x
(andy
); andyou must expect the output as a
matrix
of dimensionslength(x),length(y)
.
Interpreting that these are not all true for you, we move on. "The right function" depends on how you want the model to be run. A companion function to outer
is expand.grid
(and tidyr::crossing
, the tidyverse version), in that it creates the same combinations of the supplied vectors. For instance:
outer(c(30,60,90), c(30, 60, 100), function(x,y) {browser();1;})
# Called from: FUN(X, Y, ...)
# Browse[2]>
x
# [1] 30 60 90 30 60 90 30 60 90
# Browse[2]>
y
# [1] 30 30 30 60 60 60 100 100 100
and
eg <- expand.grid(x=c(30,60,90), y=c(30, 60, 100))
eg
# x y
# 1 30 30
# 2 60 30
# 3 90 30
# 4 30 60
# 5 60 60
# 6 90 60
# 7 30 100
# 8 60 100
# 9 90 100
(which you can then access as eg$x
and eg$y
).
Some options:
if you want your function to be called once (as with
outer
) with two arguments, and it will figure out what to do:eg <- expand.grid(x=c(30,60,90), y=c(30, 60, 100))
do.call("myfunc", eg)Note that if given
character
arguments, it will (similar todata.frame
) createfactor
s by default. It does accept thestringsAsFactors=FALSE
argument.if you want your function to be called for each pair of the vectors (so 9 times in this example), then do one either
myfunc(eg$x, eg$y)
if the number of vectors is known. If not, then using
eg
from above, thendo.call("mapply", c(myfunc, eg))
should work. Depending on the output, you can preclude it from "simplifying" the output (i.e., force a
list
output) withdo.call("mapply", c(myfunc, eg, SIMPLIFY=FALSE))
How to coerce a list object to type 'double'
If you want to convert all elements of a
to a single numeric vector and length(a)
is greater than 1 (OK, even if it is of length 1), you could unlist
the object first and then convert.
as.numeric(unlist(a))
# [1] 10 38 66 101 129 185 283 374
Bear in mind that there aren't any quality controls here. Also, X$Days
a mighty odd name.
Related Topics
R Table Function - How to Remove 0 Counts
Populate Nas in a Vector Using Prior Non-Na Values
Separate a Column into Multiple Columns Using Tidyr::Separate with Sep=""
R - Check If String Contains Dates Within Specific Date Range
Looping Over Combinations of Regression Model Terms
Display Selected Folder Path in Shiny
Converting Multiple Boolean Columns to Single Factor Column
Create All Subvectors of a Certain Length (Moving Window)
Error in Install.Packages:Type =="Both" Cannot Be Used with 'Repos =Null'
Creating Sequence of Dates for Each Group in R
Ggplot2_Error: Geom_Point Requires the Following Missing Aesthetics: Y
Read Column Names as Date Format
R - Identify Consecutive Sequences
Http Error 400 on Google_Elevation() Call
Why Isn't the R Function Sink() Writing a Summary Output to My Results File
In R, Switch Uppercase to Lowercase and Vice-Versa in a String