2022 스터디/영어 스터디[2022]

[2] S4 Classes that Contain S3 Classes

EYR 2022. 4. 10. 14:51
R: S4 Classes that Contain S3 Classes
S3Part {methods}R 문서

S3 클래스를 포함하는 S4 클래스

설명

일반(S4) 클래스는 S3클래스가 등록되어져 있다면 이를 포함할 수 있다.(setOldClass 를 호출함으로서). 여기서 서술하는 기능들은 S3클래스를 포함한 정보를 제공한다.‘기능들’ 항목 참고.

최신 버전의 R에서 이러한 기능들은 S4 클래스의 객체로 프로그래밍할 필요가 없다. 표준 계산들은 메소드 집합 S4와 S3 어느쪽에서든 문제없이 작동한다. 객체를 암시적으로 S3 클래스를 포함하도록 형 변환시키려면, 다음의 방법 중 하나를 사용하면 된다.

as(object, S3Class); as(object, "S3")

여기서 S3 클래스는 포함된 클래스의 이름으로 변환된다. 이것들은 미세하게 다른 객체를 반환한다. 아주 적은 케이스만이 구별될 필요가 있다. “S3 객체 포함” 항목 참고.

사용법

S3Part(object, strictS3 = FALSE, S3Class)

S3Class(object)

isXS3Class(classDef)

slotsFromS3(object)

## 함수들의 기능 교체는 권장되지 않는다
## 클래스에서 새 객체를 만들거나 as()의 교체버전을 사용한다.

S3Part(object, strictS3 = FALSE, needClass = ) <- value

S3Class(object) <-  value

인수

object

S3 클래스에 등록된 객체 또는 기본적인 벡터, 행렬, 배열 타입.

거의 대부분의 S3 객체의 함수는 그 고유의 S3 해석과 함께 적용될 수 있다.

strictS3

만약 TRUE이라면 값은 S4 슬롯이 제거된 S3 객체 S3Part와 함께 반환된다. 그렇지 않으면 S4 객체가 항상 반환된다. 예를 들면, S4 클래스는 setOldClass 에 의해서 만들어진다. 근본적인 S3 객체보다는 S3 클래스의 대리인으로서 작용한다.

S3Class

S3 클래스에 저장된 개체의 슬롯 character 벡터. 보통, 그리고 기본적으로 object로부터의 슬롯을 포함한다. 하지만 S3의 상위 클래스(superclass)는 허용된다.

classDef

클래스 정의 개체. getClass로 반환된다.

남아있는 변수들은 오직 권한없이 재배치된 것들에만 적용된다.

needClass

대체된 값이 이 클래스나 하위 클래스에 있을 것을 요구한다.

value

S3Part<-을 위해서 S3의 객체 부분을 위해 대체된 값.

S3 메소드 디스패치에서S3Class<-를 위해class(x)의 대체품으로 사용될 character 벡터.

함수

S3Part : setClass의 매개변수 contains= 에 나타난 S3 클래스 객체를 반환한다.

만약 strictS3 = TRUE와 함께 호출되면S3Part() 공식적으로 정의된 모든 슬롯을 제거하고 개체의 S4 bit를 해제해 기본 S3 객체를 구성한다. strictS3 = FALSE 와 함께 호출되면 객체는 S4 클래스에서 반환한다. 또한 일관성과 일반성을 위해 S3Part() 는 기본적인 벡터와 행렬, 배열 클래스들을 위해서도 작동한다.

이것에 대한 호출은 "S3"as()에 암시적 변환 된 객체에 동등하다. 이 호출은 프로그래머들이 이해하기에 더 쉽다.

S3Class: 만약 클래스가 암시적 변환된 if the class has the corresponding .S3Class 슬롯을 가지고 있다면 객체에 저장되어 있는 S3 클래스(es)의 character 벡터를 반환한다. 그렇지 않으면 이 함수는 기본적으로 class가 된다.

isXS3Class: ClassDef 에서 클래스가 어디에 정의되어있는지에 따라 TRUE 혹은 FALSE 를 반환하고 S3 클래스를 확장한다(특히, S3 클래스를 위한 슬롯이 준비되어있는지에 따라서).

slotsFromS3: 유의미한 클래스들의 슬롯 리스트나 다른 객체들을 위한 비어있는 리스트를 반환한다.

함수 slotsFromS3() 는 S3의 부분 객체와 고립된 슬롯에 접근하기 위해 내부적으로 사용되는 전역 변수이다. 이 함수를 위한 메소드는 setOldClassS4Class 와 함께 호출되었을 때 자동적으로 만들어진다. 보통은 S3 클래스를 포함한 오직 하나의 S3 슬롯뿐이지만 S4Class 매개변수는 S3 z클래스가 S4 슬롯으로 사용할 수 있는 보장된 속성을 가지고 있는 경우에 추가 슬롯을 제공할 수 있다. 추가적인 정보는 본 설명서의 다음 부분을 참고하라.setOldClass.

포함된 S3 객체

S3 클래스를 만들면 S4 클래스가 정의된다. 이 클래스로부터의 객체는 두 가지만 제외하면 본질적으로 S3의 것과 내용이 동일하다. class()라는 값을 반환하는 객체는 항상 S4 객체의 싱글 string 타입이 될 것이고isS4()TRUEFALSE 의 두 값을 반환할 것이다. 아래의 샘플을 보면 일부의 S3코드가 S4 개체와 호환되지 않을 가능성은 적다. 만약 호환되지 않는다면 as(x, "S3")를 사용하면 된다.

S3 클래스의 확장적인 클래스로부터 만들어진 객체는 몇몇 속성을 가지는 베이직 타입을 가질 것이다. S3클래스를 위해 그것은 S4와 동등할 것이다.(e.g., "data.frame"), 확장된 S4 클래스는 다른 S3 클래스를 위해 추가로 데이터 부분과 슬롯을 가질 것이다. (e.g., "lm") 확장된 S4 클래스에서 온 객체는 어떠한 베이직 타입이 될 것이고 항상 벡터 타입과 근접하다. (e.g., "list" for "lm"), 하지만 데이터 부분은 형식적 정의가 되어지지 않는다.

setOldClass 함수를 호출해 S3 클래스를 만들면 클래스 문자열의 해당 S3 벡터를 유지하기 위해서 슬롯의 이름과 같은 클래스를 만들어낸다. 같은 슬롯으로 확장된 새로운 S4 클래스들은 포함되어진 S3의 object로 설정된다. 이는 등록된 클래스의(S3) 하위 클래스(subclass)일 수 있다. 예를 들면, S4 클래스는 S3 클래스의 "lm"를 포함할 수도 있다. 그러나 클래스에서 온 객체는 "mlm""xlm"그리고 아래의 샘플을 포함할 수 있다.

R은 S3 다소 스스로 자신을 S3 등급으로 취급한다."ts" 와 같이. 하지만 "matrix""array" 는 그렇지 않다. 저것들을 확장시킨 클래스들을 위해서, S3 클래스가 포함되어 있다고 가정하면 약간의 혼란을 일으킬 수 있다. 엄청나게 혼란스러운 건 아니나, 더 나은 방법은 노골적인 '클래스'를 사용하는 것이다. 그러므로 as(x, "matrix")보단as(x, "S3")이나S3Part(x)로 처리하는게 좋다.

S3과 S4 객체: 변환 과정

R의 객체들은 S4 클래스의 것인지의 여부를 나타내는 내부 bit를 가지고 있다. 이 bit는 isS4 에 의해서 검사되어진다. 그리고asS4에 의해 설정되거나 해제될 수 있다. 그러나 이 함수는 확인하거나 해석하는 기능은 가지고 있지 않다. 그러므로 모든 사항이 올바르게 처리되었다고 확신되는 경우에만 사용해야 한다.

더 친숙한 대안으로 어떤 메소드는 가상 메소드에 명시적 변환으로 정의되었다. "S3""S4"로. 이 형식들은 as(object, "S3")as(object, "S4") 로 S3과 S4 객체들을 각각 반환한다. 게다가 그들은 가능한 방식으로 변환을 시도하고 S4로 명시적 변환할 때 그 유효성을 검사한다.

표현as(object, "S3")는 두 가지 방식으로 사용될 수 있다. 하나는 등록된 S3 클래스의 객체일 경우, 클래스 속성이 class(object)에 의해 암시되는 전체 다중 문자열 S3 클래스인지를 검사한다. 등록된 클래스에 알려진 속성이나 슬롯이 있는 경우 그것들도 제공된다.

as(object, "S3") 의 또 다른 사용법은 S4 개체를 해당 속성을 가진 S3 개체로 바꾸는 것이다. 이것은 오직 데이터 부분이 있는 S4 클래스에서만 의미가 있다. S4 메서드를 호출하지 않고 개체에 대해 작업하고 싶다면 일반적으로 이 변환이 가장 안전한 방법이다.

표현as(object, "S4") 는 S4 정의의 class(object) 개체를 만드는 개체의 속성에 사용될 것이다. 이것은 S3 연산을 통해 부분적으로 정의된 버전의 S4 객체를 생성하는 일반적인 메커니즘이다. (new를 불러오는 것과 크게 다르지 않다.) 해당 인수를 사용하지만 S4 객체가 다른 인수를 가진 초기화 메소드를 가지고 있는 경우에도 이 형식으로 사용할 수 있다.

참조

Chambers, John M. (2016) Extending R, Chapman & Hall. (Chapters 9 and 10, particularly Section 10.8)

함께보면 좋은 것

setOldClass

예시

## an "mlm" object, regressing two variables on two others

sepal <- as.matrix(datasets::iris[,c("Sepal.Width", "Sepal.Length")])
fit <- lm(sepal ~ Petal.Length + Petal.Width + Species, data = datasets::iris)
class(fit) # S3 class: "mlm", "lm"

## a class that contains "mlm"
myReg <- setClass("myReg", slots = c(title = "character"), contains = "mlm")

fit2 <- myReg(fit, title = "Sepal Regression for iris data")

fit2 # shows the inherited "mlm" object and the title

identical(S3Part(fit2), as(fit2, "mlm"))

class(as(fit2, "mlm")) # the S4 class, "mlm"

class(as(fit2, "S3")) # the S3 class, c("mlm", "lm")

## An object may contain an S3 class from a subclass of that declared:
xlm <- setClass("xlm", slots = c(eps = "numeric"), contains = "lm")

xfit <- xlm(fit, eps = .Machine$double.eps)

xfit@.S3Class # c("mlm", lm")



[Package methods version 4.1.2 Index]