yaxt - xlab size in r




동일한 객체 조 변경 (2)

identical 것은 단순히 너무 느슨한 것이지만 다음과 같이 변경할 수 있습니다 :

> identical(x, y, attrib.as.set = FALSE)
[1] FALSE

그 이유는 더 자세히 객체를 검사하여 찾을 수 있습니다 :

> dput(x)
structure(list(x = 1:3, y = 11:13), .Names = c("x", "y"), row.names = c(NA,
-3L), class = "data.frame")
> dput(y)
structure(list(x = 1:3, y = 11:13), .Names = c("x", "y"), row.names = c(NA,
3L), class = "data.frame")

별개의 row.names 속성에 유의하십시오.

> .row_names_info(x)
[1] -3
> .row_names_info(y)
[1] 3

문서에서 음수는 자동 rownames ( x )를 의미하는 반면, y 의 행 이름은 자동이 아닙니다. 그리고 as.matrix 는 그것들을 다르게 취급합니다.

나는 이상한 결과를 오늘 얻었다.

이를 복제하려면 다음 데이터 프레임을 고려하십시오.

x <- data.frame(x=1:3, y=11:13)
y <- x[1:3, 1:2] 

그들은 있어야하고 실제로 동일합니다 :

identical(x,y)
# [1] TRUE

indentical 객체에 t() 를 적용하면 같은 결과가 발생하지만,

identical(t(x),t(y))
# [1] FALSE

차이점은 열 이름에 있습니다.

colnames(t(x))
# NULL
colnames(t(y))
# [1] "1" "2" "3"

이것을 감안할 때, y 를 칼럼으로 쌓고 싶다면 당신이 기대하는 것을 얻을 수 있습니다 :

stack(as.data.frame(t(y)))
#   values ind
# 1      1   1
# 2     11   1
# 3      2   2
# 4     12   2
# 5      3   3
# 6     13   3

동안:

stack(as.data.frame(t(x)))
#     values ind
# 1      1  V1
# 2     11  V1
# 3      2  V2
# 4     12  V2
# 5      3  V3
# 6     13  V3

후자의 경우 as.data.frame() 은 원래 열 이름을 찾지 않고 자동으로 생성합니다.

범인은 t() 의해 호출 된 as.matrix() t() .

rownames(as.matrix(x))
# NULL
rownames(as.matrix(y))
# [1] "1" "2" "3"

해결 방법은 rownames.force 를 설정하는 rownames.force .

rownames(as.matrix(x, rownames.force=TRUE))
# [1] "1" "2" "3"
rownames(as.matrix(y, rownames.force=TRUE))
# [1] "1" "2" "3"
identical(t(as.matrix(x, rownames.force=TRUE)), 
          t(as.matrix(y, rownames.force=TRUE)))
# [1] TRUE

( stack(...) 호출을 적절히 다시 작성하십시오.)

내 질문은 다음과 같습니다.

  1. as.matrix() xy 다르게 취급하는 이유는 무엇입니까?

  2. 어떻게 그 차이를 알 수 있습니까?

다른 정보 함수는 x, y 사이의 차이를 나타내지 않습니다.

identical(attributes(x), attributes(y))
# [1] TRUE
identical(str(x), str(y))
# ...
#[1] TRUE

솔루션에 대한 의견

Konrad Rudolph 는 위에서 설명한 행동에 간결하면서도 효과적인 설명을합니다 (자세한 내용은 mt1022 참조).

간단히 말해서 Konrad는 다음과 같이 보여줍니다 :

a) xy내부적으로 다릅니다.
b) "내부적 인 차이"를 포착하기 위해 " identical 또한 기본적으로 너무 느슨합니다".

자, S 모든 원소를 가진 집합 S 의 부분 집합 T 를 취하면, ST 는 정확히 같은 대상입니다. 따라서, x 모든 행과 열을 가진 데이터 프레임 y 를 취하면 xy 정확히 같은 객체 여야 합니다. 불행히도 x \neq y !
이 문제는 반 직관적 일뿐만 아니라 혼란 스럽기도합니다. 즉, 차이점은 자명하지 않지만 내부 및 기본 identical 기능조차도이를 볼 수 없습니다.

또 다른 자연적 원리는 두 개의 동일한 (매트릭스와 같은) 객체를 전치시키는 것이 동일한 객체를 생성한다는 것입니다. 다시 말하지만, 이것은 이전하기 전에 identical 것이 "너무 느리다"는 사실에 의해 깨졌습니다. 전치시킨 후에는 그 차이점을보기에 충분 identical .

IMHO이 동작은 (버그가 아니더라도) R과 같은 과학적 언어에 대한 오해입니다.
바라기를이 포스트는 약간주의를 모을 것이고 R 팀은 그것을 개정하는 것을 고려할 것이다.


주석에서와 같이 xy 는 엄격하게 동일하지 않습니다. tt.data.frame 호출하면 t.data.frame 이 실행됩니다.

function (x) 
{
    x <- as.matrix(x)
    NextMethod("t")
}

보시 as.matrix , as.matrix.data.frame 호출합니다. as.matrix.data.frame :

function (x, rownames.force = NA, ...) 
{
    dm <- dim(x)
    rn <- if (rownames.force %in% FALSE) 
        NULL
    else if (rownames.force %in% TRUE) 
        row.names(x)
    else if (.row_names_info(x) <= 0L) 
        NULL
    else row.names(x)
...

@oropendola에 의해 주석 처리 된 바와 같이, xy.row_names_info 의 리턴은 다르다. 위의 함수는 차이가 적용되는 곳이다.

그럼 왜 y 가 다른 rownames ? [.data.frame 보자. 핵심 줄에 주석을 추가했다.

{
    ... # many lines of code
    xx <- x  #!! this is where xx is defined
    cols <- names(xx)
    x <- vector("list", length(x))
    x <- .Internal(copyDFattr(xx, x))  # This is where I am not sure about
    oldClass(x) <- attr(x, "row.names") <- NULL
    if (has.j) {
        nm <- names(x)
        if (is.null(nm)) 
            nm <- character()
        if (!is.character(j) && anyNA(nm)) 
            names(nm) <- names(x) <- seq_along(x)
        x <- x[j]
        cols <- names(x)
        if (drop && length(x) == 1L) {
            if (is.character(i)) {
                rows <- attr(xx, "row.names")
                i <- pmatch(i, rows, duplicates.ok = TRUE)
            }
            xj <- .subset2(.subset(xx, j), 1L)
            return(if (length(dim(xj)) != 2L) xj[i] else xj[i, 
                                                            , drop = FALSE])
        }
        if (anyNA(cols)) 
            stop("undefined columns selected")
        if (!is.null(names(nm))) 
            cols <- names(x) <- nm[cols]
        nxx <- structure(seq_along(xx), names = names(xx))
        sxx <- match(nxx[j], seq_along(xx))
    }
    else sxx <- seq_along(x)
    rows <- NULL ## this is where rows is defined, as we give numeric i, the following
    ## if block will not be executed
    if (is.character(i)) {
        rows <- attr(xx, "row.names")
        i <- pmatch(i, rows, duplicates.ok = TRUE)
    }
    for (j in seq_along(x)) {
        xj <- xx[[sxx[j]]]
        x[[j]] <- if (length(dim(xj)) != 2L) 
            xj[i]
        else xj[i, , drop = FALSE]
    }
    if (drop) {
        n <- length(x)
        if (n == 1L) 
            return(x[[1L]])
        if (n > 1L) {
            xj <- x[[1L]]
            nrow <- if (length(dim(xj)) == 2L) 
                dim(xj)[1L]
            else length(xj)
            drop <- !mdrop && nrow == 1L
        }
        else drop <- FALSE
    }
    if (!drop) { ## drop is False for our case
        if (is.null(rows)) 
            rows <- attr(xx, "row.names")  ## rows changed from NULL to 1,2,3 here
        rows <- rows[i]
        if ((ina <- anyNA(rows)) | (dup <- anyDuplicated(rows))) {
            if (!dup && is.character(rows)) 
                dup <- "NA" %in% rows
            if (ina) 
                rows[is.na(rows)] <- "NA"
            if (dup) 
                rows <- make.unique(as.character(rows))
        }
        if (has.j && anyDuplicated(nm <- names(x))) 
            names(x) <- make.unique(nm)
        if (is.null(rows)) 
            rows <- attr(xx, "row.names")[i]
        attr(x, "row.names") <- rows  ## this is where the rownames of x changed
        oldClass(x) <- oldClass(xx)
    }
    x
}

우리는 yattr(x, 'row.names') 와 같은 것으로 이름을 얻는 것을 볼 수 있습니다 :

> attr(x, 'row.names')
[1] 1 2 3

그래서 우리는 [.data.frame 하여 y 를 만들었을 때 x 와는 다른 row.names 속성을받습니다. row.names 속성은 row.names 가 자동이고 dput 결과에 음수 부호가 dput 됩니다.

편집하다

사실, 이것은 row.names 매뉴얼에 명시되어 있습니다 :

노트

row.names는 배열의 rownames와 비슷하며 배열 인수로 rownames를 호출하는 메서드를 가지고 있습니다.

n> 2에 대한 1 : n 양식의 행 이름은 내부적으로 C 코드 또는 디파 싱 (deparsing)으로 볼 수 있지만 row.names 또는 attr (x, "row.names")를 통해서는 볼 수없는 압축 된 형식으로 저장됩니다. 또한이 정렬의 일부 이름은 '자동'으로 표시되고 as.matrix 및 data.matrix (및 잠재적으로 다른 함수)에 의해 다르게 처리됩니다.

그래서 attr 은 자동 row.names ( x 그것과 row.names )와 명시 적 interger row.names ( y 그것과 같다)를 구별하지 않는다. 이것은 내부 표현 .row_names_info 통해 as.matrix 의해 구별된다.





transpose