【发布时间】:2016-03-10 17:30:51
【问题描述】:
我正在创建一个 S3 类,其中构造函数有多个参数。我想将等长向量传递给构造函数并取回我的新类的对象向量。
myclass <- function(number, letter) {
this <- list(
num = number,
let = letter
)
class(this) <- append(class(this), "myclass")
return(this)
}
df <- data.frame(a = 1:5, b = letters[1:5])
c <- myclass(df$a, df$b)
但 c 不是 myclass 类型的 5 个对象的列表,而是 2 个对象的列表:
> str(c)
List of 2
$ num: int [1:5] 1 2 3 4 5
$ let: Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
- attr(*, "class")= chr [1:2] "list" "myclass"
我可以更改构造函数以使其工作,还是应该使用一些应用函数来调用构造函数?
如果是后者,那么我也无法使用它 - 我认为 mapply 是解决方案,但不是..
编辑:感谢@rawr 的评论,我现在知道c <- mapply(myclass, df$a, df$b, SIMPLIFY = FALSE) 是在这里使用mapply 函数的正确方法,但我们仍然面临着属于构造函数内部还是代码内部的问题调用构造函数。
> c <- mapply(myclass, df$a, df$b)
> str(c)
List of 10
$ : int 1
$ : Factor w/ 5 levels "a","b","c","d",..: 1
$ : int 2
$ : Factor w/ 5 levels "a","b","c","d",..: 2
$ : int 3
$ : Factor w/ 5 levels "a","b","c","d",..: 3
$ : int 4
$ : Factor w/ 5 levels "a","b","c","d",..: 4
$ : int 5
$ : Factor w/ 5 levels "a","b","c","d",..: 5
- attr(*, "dim")= int [1:2] 2 5
- attr(*, "dimnames")=List of 2
..$ : chr [1:2] "num" "let"
..$ : NULL
> class(c[[1]])
[1] "integer"
我认为这个显式循环给出了正确的结果:
c <- list()
for(i in 1:5) {
c[[i]] <- myclass(df$a[i], df$b[i])
}
> str(c)
List of 5
$ :List of 2
..$ num: int 1
..$ let: Factor w/ 5 levels "a","b","c","d",..: 1
..- attr(*, "class")= chr [1:2] "list" "myclass"
$ :List of 2
..$ num: int 2
..$ let: Factor w/ 5 levels "a","b","c","d",..: 2
..- attr(*, "class")= chr [1:2] "list" "myclass"
$ :List of 2
..$ num: int 3
..$ let: Factor w/ 5 levels "a","b","c","d",..: 3
..- attr(*, "class")= chr [1:2] "list" "myclass"
$ :List of 2
..$ num: int 4
..$ let: Factor w/ 5 levels "a","b","c","d",..: 4
..- attr(*, "class")= chr [1:2] "list" "myclass"
$ :List of 2
..$ num: int 5
..$ let: Factor w/ 5 levels "a","b","c","d",..: 5
..- attr(*, "class")= chr [1:2] "list" "myclass"
>
> class(c[[1]])
[1] "list" "myclass"
但我会重复我认为更重要的问题: 我可以更改构造函数以使其工作,还是应该使用一些应用函数(或循环)来调用构造函数?
【问题讨论】:
-
在你的 mapply 中使用不要使用简化?
str(mapply(myclass, df$a, df$b, SIMPLIFY = FALSE)) -
您是否希望
myclass仅输出 2 项length == 1的“列表”,或者您是否有可能需要myclass(df$a, df$b)原样?如果是第一个,我想你必须在myclass中添加一个循环来“矢量化”它;如果是第二个,那么在需要时添加一个循环可能会更方便,比如 rawr 的。 -
SIMPLIFY = FALSE部分肯定修复了mapply功能,谢谢@rawr。这个问题现在变成了设计哲学之一——它属于构造函数,还是调用构造函数的代码? -
@alexis_laz 我不明白你所做的区分 - 你所说的“原样”是什么意思?
-
@BrianStamper :您是否正在寻找如何在
myclass内循环,或者更合适的方法?如果像myclass(df$a, df$b)这样的输出(当前在您的问题中定义的myclass)永远不可取,那么我想您需要在myclass内添加循环以避免每次调用时调用循环函数myclass.
标签: r oop constructor vectorization