[r] data.frame 또는 행렬을 사용해야합니까?

언제을 사용해야하고 언제을 사용하는 data.frame것이 더 낫 matrix습니까?

둘 다 데이터를 직사각형 형식으로 유지하기 때문에 때때로 불분명합니다.

언제 어떤 데이터 유형을 사용해야하는지에 대한 일반적인 규칙이 있습니까?



답변

답변의 일부는 이미 귀하의 질문에 포함되어 있습니다 : 열 (변수)이 다른 유형 (숫자 / 문자 / 논리 등) 일 것으로 예상되는 경우 데이터 프레임을 사용하십시오. 행렬은 같은 유형의 데이터를위한 것입니다.

결과적으로, matrix / data.frame 선택은 동일한 유형의 데이터가있는 경우에만 문제가됩니다.

답은 data.frame / matrix의 데이터로 수행하려는 작업에 따라 다릅니다. 다른 함수로 전달 될 경우 이러한 함수의 예상 인수 유형이 선택을 결정합니다.

또한:

행렬은 더 메모리 효율적입니다.

m = matrix(1:4, 2, 2)
d = as.data.frame(m)
object.size(m)
# 216 bytes
object.size(d)
# 792 bytes

선형 대수 유형의 연산을 수행하려는 경우 행렬이 필요합니다.

데이터 프레임은 이름으로 열을 자주 참조하는 경우 (콤팩트 $ 연산자를 통해) 더 편리합니다.

각 열에 개별적으로 서식을 적용 할 수 있으므로 테이블 형식 정보를보고 (인쇄)하는 데 데이터 프레임이 더 좋습니다.


답변

@Michal이 언급하지 않은 것은 동등한 데이터 프레임보다 작은 매트릭스 일뿐 만 아니라 행렬을 사용하면 데이터 프레임을 사용하는 것보다 훨씬 효율적으로 코드를 훨씬 효율적으로 만들 수 있다는 것입니다. 이것이 내부적으로 많은 R 함수가 데이터 프레임에있는 행렬 데이터로 강제되는 이유입니다.

데이터 프레임은 종종 훨씬 더 편리합니다. 항상 원자 적으로 만 존재하는 것은 아닙니다.

문자 행렬을 가질 수 있습니다. R로 행렬을 만들기 위해 숫자 데이터를 가질 필요는 없습니다.

데이터 프레임을 행렬 data.matrix()로 변환 할 때는 내부 수준에 따라 요소를 숫자 값으로 변환하여 적절히 처리 하는 함수 가 있습니다. as.matrix()인자 레이블이 숫자가 아닌 경우 비아 를 강제 변환 하면 문자 행렬이 생성됩니다. 비교:

> head(as.matrix(data.frame(a = factor(letters), B = factor(LETTERS))))
     a   B
[1,] "a" "A"
[2,] "b" "B"
[3,] "c" "C"
[4,] "d" "D"
[5,] "e" "E"
[6,] "f" "F"
> head(data.matrix(data.frame(a = factor(letters), B = factor(LETTERS))))
     a B
[1,] 1 1
[2,] 2 2
[3,] 3 3
[4,] 4 4
[5,] 5 5
[6,] 6 6

나는 종종 숫자 변수 이상을 가지고 있기 때문에 거의 항상 데이터 분석 작업에 데이터 프레임을 사용합니다. 패키지의 함수를 코딩 할 때는 거의 항상 행렬로 강제 변환 한 다음 결과를 데이터 프레임으로 다시 형식화합니다. 데이터 프레임이 편리하기 때문입니다.


답변

@Michal : 행렬은 실제로 더 효율적인 메모리는 아닙니다.

m <- matrix(1:400000, 200000, 2)
d <- data.frame(m)
object.size(m)
# 1600200 bytes
object.size(d)
# 1600776 bytes

… 열 수가 많은 경우가 아니면 :

m <- matrix(1:400000, 2, 200000)
d <- data.frame(m)
object.size(m)
# 1600200 bytes
object.size(d)
# 22400568 bytes


답변

행렬은 실제로 추가 방법이있는 벡터입니다. data.frame은 목록입니다. 차이점은 벡터 대리스트입니다. 계산 효율성을 위해 매트릭스를 사용하십시오. 필요한 경우 data.frame을 사용하십시오.


답변

행렬과 데이터 프레임은 사각형 2D 배열이며 행과 열로 이기 종일 수 있습니다
. 그것들은 일부 메소드와 속성을 공유하지만 전부는 아닙니다.

예 :

M <- list(3.14,TRUE,5L,c(2,3,5),"dog",1i)  # a list
dim(M) <- c(2,3)                           # set dimensions
print(M)                                   # print result

#      [,1]  [,2]      [,3]
# [1,] 3.14  5         "dog"
# [2,] TRUE  Numeric,3 0+1i

DF <- data.frame(M)                   # a data frame
print(DF)                             # print result

#      X1      X2   X3
#  1 3.14       5  dog
#  2 TRUE 2, 3, 5 0+1i

M <- matrix(c(1,1,1,1,2,3,1,3,6),3)   # a numeric matrix
DF <- data.frame(M)                   # a all numeric data frame

solve(M)                              # obtains inverse matrix
solve(DF)                             # obtains inverse matrix
det(M)                                # obtains determinant
det(DF)                               # error


답변

나는 둘 사이의 효율성 차이를 더 강조 할 수 없다! DF가 특히 데이터 분석 사례에서 더 편리하다는 것은 사실이지만, 이기종 데이터도 허용하고 일부 라이브러리는 이러한 데이터 만 허용하지만 특정 작업에 대한 일회성 코드를 작성하지 않는 한 이러한 라이브러리는 모두 보조입니다.

예를 들어 보겠습니다. MCMC 방법의 2D 경로를 계산하는 기능이있었습니다. 기본적으로 이것은 초기 지점 (x, y)을 취하고 특정 알고리즘을 반복하여 각 단계에서 새로운 지점 (x, y)을 찾아 전체 경로를 구성합니다. 알고리즘은 매우 복잡한 함수를 계산하고 각 반복에서 임의의 변수를 생성하는 것을 포함하므로 12 초 동안 실행될 때 각 단계에서 얼마나 많은 작업을 수행하는 것이 좋을 것이라고 생각했습니다. 즉, 함수는 3 열 데이터 프레임에서 목적 함수의 값과 함께 구성된 경로의 모든 포인트를 수집했습니다. 따라서 3 열은 그다지 크지 않으며 단계 수도 10,000보다 합리적입니다 (이러한 문제에서 길이 1,000,000의 경로는 일반적이므로 10,000은 아무것도 아닙니다). 그래서 저는 DF 10을 생각했습니다. 000×3은 확실히 문제가되지 않습니다. DF가 사용 된 이유는 간단합니다. 함수를 호출 한 후 ggplot ()이 호출되어 결과 (x, y) 경로를 그립니다. 그리고 ggplot ()은 행렬을 허용하지 않습니다.

그런 다음 호기심을 벗어난 시점에서 행렬에서 경로를 수집하도록 함수를 변경하기로 결정했습니다. 다행스럽게도 DF와 행렬의 구문은 비슷하지만 df를 data.frame으로 지정하는 행을 행렬로 초기화하는 행으로 변경하는 것이 전부였습니다. 여기서 초기 코드에서 DF가 최종 크기를 갖도록 초기화되었으므로 나중에 함수 코드에서 새로운 값만 이미 할당 된 공간에 기록되었으며 새 행을 추가하는 오버 헤드가 없었습니다. DF. 이것은 비교를 더욱 공정하게 만들고 함수에서 더 이상 아무것도 다시 쓸 필요가 없으므로 작업을 더 단순하게 만들었습니다. 필요한 크기의 data.frame의 초기 할당에서 동일한 크기의 행렬로 한 줄만 변경됩니다. 새 버전의 함수를 ggplot ()에 적용하기 위해, 이제 반환 된 행렬을 데이터로 변환했습니다.

코드를 다시 실행 한 후 결과를 믿을 수 없었습니다. 코드는 순식간에 실행됩니다! 약 12 초 대신. 다시 말하지만, 10,000 회 반복 동안의 함수는 DF (및 이제는 매트릭스)의 이미 할당 된 공간에 대한 값만 읽고 씁니다. 그리고이 차이는 합리적인 (또는 다소 작은) 크기 10000×3에도 적용됩니다.

따라서 DF를 사용하는 유일한 이유가 ggplot ()과 같은 라이브러리 함수와 호환되도록하는 것이라면 마지막 순간에 언제든지 DF로 변환 할 수 있습니다. 편리하다고 느끼는 한 행렬로 작업하십시오. 반면에 행렬에서 DF로 또는 그 반대로 상수 변환해야하는 일부 데이터 분석 패키지를 사용하거나 집중 계산을 직접 수행하지 않고 표준 만 사용하는 등 DF를 사용해야하는보다 실질적인 이유가있는 경우 패키지 (많은 것들이 실제로 DF를 매트릭스로 내부적으로 변환하고, 작업을 수행 한 다음 결과를 다시 변환하여 모든 효율성 작업을 수행합니다) 또는 일회성 작업을 수행하므로 걱정하지 않아도됩니다. DF에 더 편안하면 효율성에 대해 걱정할 필요가 없습니다.

또는 다른 실제 규칙 : OP와 같은 질문이있는 경우 행렬을 사용하십시오. 따라서 그러한 질문이없는 경우에만 DF를 사용하십시오 (이미 DF를 사용해야한다는 것을 알고 있기 때문에 또는 코드가 일회성이므로 실제로 신경 쓰지 않습니다.)

그러나 일반적으로이 효율성 지점을 항상 우선 순위로 유지하십시오.


답변