繁体   English   中英

使用R函数“外部”时出现“尺寸[产品xx]与对象[xx]的长度不匹配”错误

[英]“dims [product xx] do not match the length of object [xx]” error in using R function `outer`

x <- 1:9
names(x) <- paste0("x",x)
y <- 2:5
names(y) <- paste0("y",y)

fun1      <-function(a, b) {paste(class(a),b, sep = "**")} #works
funError  <-function(a, b) {paste(class(a),class(b), sep = "**")} #does not work with outer
funNoError<-function(a, b) {paste(a,class(a),class(b),b, sep = "**")}  #works with outer  

funError(1,2) #is a valid function
outer(x, y, "funError") # fails
outer(x, y, "funNoError") # works

问题1 :为什么outer(x, y, "funError")不起作用?

dim(robj)<-c(dX,dY)中的错误:昏暗[产品36]与对象[1]的长度不匹配

Q2 :为什么outer(x, y, "funNoError")起作用? 它非常相似。

  • 我可以看到的唯一区别是funError每个“结果”都是相同的( "numeric**numeric" )。

  • 如果始终具有相同的值就是问题:为什么这在这里起作用?

outer(rep(0,7), 1:10, "^")


好吧,我明白了:

lol  <- function(a,b) {"lol"}
lol_v<- Vectorize(lol)

outer(x, y, "lol")   # fails with same Error
outer(x, y, "lol_v") # works as expected

xy都是向量时outer(x, y, FUN)我经常用以下内容解释outer(x, y, FUN)

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失败是因为zz长度为1,而funNoError并不是因为粘贴a (长度大于1的向量)和class(a) (长度为1的向量)时应用了“回收规则”。

这是说明性的,因为您将看到为什么outer(1:5, 1:5, "+")有效,而outer(1:5, 1:5, sum)失败了。 基本上, FUN必须能够按元素处理xxyy 否则,用名为Vectorize的糖函数包装FUN 稍后将提供更多详细信息。

请注意,“列表”也是向量的有效模式。 因此outer可以用于一些非标准的事情,例如如何执行成对的运算(如`%in%`)并为向量列表设置运算


您也可以将矩阵/数组传递给outer 假设它们只是具有“ dim”属性(可选地具有“ dimnames”)的矢量,则outer工作方式不会改变。

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用通俗易懂的语言解释了上面的代码。

 ‘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).

单词“矢量” 不是 讨论最多的一个R中的表现 它的意思是“向量化函数的作用”:

## 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) )

有些函数说"+""*"paste行为是这样的,但是其他一些函数则没有,例如classsumprod R中的*apply系列函数可以帮助您向量化函数操作,也可以编写自己的循环来达到相同的效果。


另一个值得一读的优质问答: 为什么外部工作没有按照我认为的方式(在R中)?

我认为这是因为从外部得到的矩阵期望与您输入的维度相同,但是class(a)仅是长度1,因此矩阵维度不匹配。 尝试

funError2 <- function(a,b){paste(rep(class(a), length(a)),rep(class(b), length(b)), sep = "**")}
outer(x,y, "funError2")
#>    y2                 y3                 y4                
#> x1 "integer**integer" "integer**integer" "integer**integer"
#> x2 "integer**integer" "integer**integer" "integer**integer"
#> x3 "integer**integer" "integer**integer" "integer**integer"
#> x4 "integer**integer" "integer**integer" "integer**integer"
#> x5 "integer**integer" "integer**integer" "integer**integer"
#> x6 "integer**integer" "integer**integer" "integer**integer"
#> x7 "integer**integer" "integer**integer" "integer**integer"
#> x8 "integer**integer" "integer**integer" "integer**integer"
#> x9 "integer**integer" "integer**integer" "integer**integer"
#>    y5                
#> x1 "integer**integer"
#> x2 "integer**integer"
#> x3 "integer**integer"
#> x4 "integer**integer"
#> x5 "integer**integer"
#> x6 "integer**integer"
#> x7 "integer**integer"
#> x8 "integer**integer"
#> x9 "integer**integer"

reprex软件包 (v0.2.0)创建于2018-09-13。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM