목록 인 슬롯이있는 S4 클래스를 정의했습니다. 해당 목록에 새 항목을 추가하는 방법 (Genolini의 S4 소개-섹션 10.2)을 작성했습니다.
setClass("MyClass",
slots = c(entries = "list")
)
a1 <- new("MyClass", entries = list(1))
setGeneric(name="MyAppend",
def=function(.Object, newEntry)
{
standardGeneric("MyAppend")
}
)
setMethod(f = "MyAppend",
signature = "MyClass",
definition = function(.Object, newEntry){
nameObject <- deparse(substitute(.Object))
newlist <- .Object@entries
n <- newlist %>% length
newlist[[n + 1]] <- newEntry
.Object@entries <- newlist
assign(nameObject, .Object, envir = parent.frame())
return(invisible)
}
)
내가 달리면
MyAppend(a1, 2)
a1
나는 얻다
R>a1
An object of class "MyClass"
Slot "entries":
[[1]]
[1] 1
[[2]]
[1] 2
그래야만합니다.
그러나 내 응용 프로그램에서는 동적으로 업데이트 할 개체의 이름을 생성합니다.
ObjectName <- paste0("a", 1)
그런 다음 그 이름을 객체 자체로 바꿀 수 있습니다.
Object <- ObjectName %>% sym %>% eval
그런 다음 str(Object)
반환
Formal class 'MyClass' [package ".GlobalEnv"] with 1 slot
..@ entries:List of 3
.. ..$ : num 1
.. ..$ : num 2
다시 말하지만 그래야만합니다.
하지만 내가 달릴 때
MyAppend(Object, 3)
Object
a1
동안 Object
업데이트 a1
되지 않았 음 을 보여주는 다음이 표시 됩니다 .
R>Object
An object of class "MyClass"
Slot "entries":
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
R>
R>a1
An object of class "MyClass"
Slot "entries":
[[1]]
[1] 1
[[2]]
[1] 2
내가 뭘 잘못하고 있니?
문제는 다음 줄입니다.
Object <- ObjectName %>% sym %>% eval
당신이 생각하는대로하지 않습니다. 오른쪽은 객체로 평가 a1
되므로 수행하는 것과 다르지 않습니다.
Object <- a1
그러나 이것은의 복사본 을 a1
생성하고에 대한 참조 나 포인터 또는 동의어를 생성하지 않습니다 a1
.
이다 통과하여 (종류의)에 대한 참조를 만들 수 평가되지 않은 당신이 당신의 일반적인 방법에 추가하고자하는 객체의 이름입니다. 당신이 떠날 경우 eval
의 일부가 ObjectName %>% sym %>% eval
다음 개체를 할당됩니다 이름 a1
에 대한 참조로 전달 될 수 개체를 a1
.
그러나 이것은 새로운 문제를 남깁니다 . MyAppend
class의 객체로 무엇을해야할지 모릅니다 name
. 따라서 이름을 처리하는 데 적합한 방법을 작성해야합니다.
setMethod(f = "MyAppend",
signature = "name",
definition = function(.Object, newEntry){
stopifnot(class(eval(.Object)) == "MyClass")
objname <- as.character(.Object)
.Object <- eval(.Object)
.Object@entries <- append(.Object@entries, newEntry)
assign(as.character(objname), .Object, envir = parent.frame())
}
)
이제 이것이 어떻게 작동하는지 봅시다 :
a1 <- new("MyClass", entries = list(1))
a1
#> An object of class "MyClass"
#> Slot "entries":
#> [[1]]
#> [1] 1
MyAppend(a1, 2)
a1
#> An object of class "MyClass"
#> Slot "entries":
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 2
Object <- paste0("a", 1) %>% sym()
MyAppend(Object, 3)
a1
#> An object of class "MyClass"
#> Slot "entries":
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 2
#>
#> [[3]]
#> [1] 3
나는 이것이 당신이 의도 한 것이라고 생각합니다. 이 워크 플로우를 더 쉽게 만들기 위해 문자열을 디스패치하는 메소드를 고려할 수 있습니다 (문자열로 get
전달 된 이름에서 객체를 검색하기 위해 메소드 내부를 사용 합니다).
내가 당신 자신의 기능도 변경했음을 주목하라. return(invisible)
이것은 내장 함수의 본문을 반환하기 때문에 하지 말아야 합니다 invisible
. return 문을 모두 제외하십시오. 내장 함수 append
를 사용하여 메서드를 MyClass
좀 더 간단 하게 만들 수도 있습니다 .
setMethod(f = "MyAppend",
signature = "MyClass",
definition = function(.Object, newEntry){
nameObject <- deparse(substitute(.Object))
.Object@entries <- append(.Object@entries, newEntry)
assign(nameObject, .Object, envir = parent.frame())
}
)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다