2012-05-16 1 views
6

colMeans 함수에 관한 질문이 있습니다. 길이가 1 인 열로 실행될 때 오류를 반환하지 않는 버전이 있습니까? 나는이 기능은 각 컬럼에 의미 적용하는 경우 colMeans는 R에서 작동하고 크기가 1 인 열에 문제가 있음

temp<-cbind(c(2,2),c(3,4)) 
colMeans(temp) 

[1] 2.0 3.5 

하지만이 하나

temp2<-c(2,2) 
colMeans(temp2) 

Error in colMeans(temp2) : 
'x' must be an array of at least two dimensions 

그러나 예를 들어

를 들어, 제대로 내가 쓴 2의 값과 2

와 함께 제공 이 작업을 수행하는 함수

testfun<-function(i,x){ 
mean(x[,i]) 
} 
sapply(1:ncol(x),testfun,x) 

이는 colMeans와 동일한 결과를 제공합니다.
colMeans가이 메서드보다 훨씬 빠르다고 들었습니다. 그래서, 열의 크기가 1 일 때 작동 할 colMeans 버전이 있습니까?

답변

7

같이 colMeans는 기대 (?colMeans)에서 그 x 인수 "둘 이상의 차원의 어레이". 그러나 temp2

is.array(temp2) 
# [1] FALSE 

temp2 배열로 만들 수 있습니다 배열이 아닌 :

array(temp2, dim = c(2, 2))[1, ] 

같은 아마도 temp2 배열을 서브 세트에서 온

(tempArray <- array(temp2, dim = c(1, 2))) 
#  [,1] [,2] 
# [1,] 2 2 

colMeans(tempArray) 
# [1] 2 2 

하지만 이것은 아니다 정렬. 배열로 유지하려면 괄호 안에 drop = FALSE을 추가

array(temp2, dim = c(2, 2))[1, , drop = FALSE] 
#  [,1] [,2] 
# [1,] 2 2 

는 그런 다음 서브 세트 배열에 colMeans를 사용할 수 있습니다.

4

colMeans 기능은 n 차원 배열을위한 것입니다. 열의 크기가 1 (1 열 또는 1 행 ??)이면 효과적으로 벡터가 생깁니다. 벡터에서 단지 mean을 사용하는 것이 좋습니다. 백만 수의 평균을 계산 속도의 측면에서 매우 빠르게 : @ 폴 지적

> system.time(mean(runif(10e5))) 
    user system elapsed 
    0.038 0.000 0.038 
2

@PaulHiemstra 및 @BenBarnes가 정답을 제공합니다. 나는 그들의 설명에 덧붙이고 싶다.

벡터 대 배열

벡터 목록의 특별한 종류를 제외하고 (심지어리스트 거의 모든 내부적 벡터로 표현된다 R.에서 기본 데이터 구조이며, 점선 쌍의 목록, ?list 참조). 배열은 속성이 첨부 된 벡터인데 객체의 크기를 나타내는 dim 속성이 있습니다. 다음 고려 :

v <- c(1:10) 
a <- array(v, dim = c(5, 2)) 
length(v) # 10 
length(a) # 10 
attributes(v) # NULL 
attributes(a) # $dim 10 1 
is.vector(v) # TRUE 
is.array(v) # FALSE 
is.vector(a) # FALSE 
is.array(a) # TRUE 

모두 va 길이 10 있습니다. 유일한 차이점은 dim 속성이 연결된 a입니다. 이 추가 된 특성으로 인해 R은 a을 벡터 대신 배열로 외부에서 처리합니다.단지 dim 속성을 수정하면 배열에서 벡터와 뒤쪽에 물체의 R의 외부 표현을 변경할 수 있습니다

당신의 예에서
attr(a, "dim") <- NULL 
is.vector(a) # TRUE 
is.array(a) # FALSE 
attr(v, "dim") <- c(5, 2) 
is.vector(v) # FALSE 
is.array(v) # TRUE 

, temp2는 벡터 개체입니다, 따라서 dim 속성을 부족. colMeansdim 속성이 길이 2 (2 차원) 이상인 array 개체가 필요합니다. 쉽게 하나의 컬럼이있는 2 차원 배열 temp2을 변환 할 수

temp3 <- array(temp2, dim = c(length(temp2), 1)) 
# or: 
temp4 <- temp2 
attr(temp4, "dim") <- c(length(temp2), 1) 
is.array(temp2) # FALSE 
is.array(temp3) # TRUE 
is.array(temp4) # TRUE 

colMeans()을 비교)은 (평균

@PaulHiemstra 대신 단일 컬럼 벡터 변환 옳다 colMeans()의 경우 벡터에 mean()을 사용하는 것이 훨씬 더 일반적입니다. 그러나 colMeans()이 빠르다는 것이 맞습니다. 이것은 올바른 형식의 데이터를 검사하는 횟수가 줄어들 기 때문이라고 생각하지만 내부 C 코드를 살펴 봐야합니다. 예를 고려 어레이

# Create vector "v" and array "a" 
n <- 10e7 
set.seed(123) # Set random number seed to ensure "v" and "a[,1]" are equal 
v <- runif(n) 
set.seed(123) # Set random number seed to ensure "v" and "a[,1]" are equal 
a <- array(runif(n), dim=c(n, 1)) 

# Test that "v" and "a[,1]" are equal 
all.equal(v, a[,1]) # TRUE 

# Functions to compare 
f1 <- function(x = v){mean(x)} # Using mean on vector 
f2 <- function(x = a){mean(x)} # Using mean on array 
f3 <- function(x = a){colMeans(x)} # Using colMeans on array 

# Compare elapsed time 
system.time(f1()) # elapsed time = 0.344 
system.time(f2()) # elapsed time = 0.366 
system.time(f3()) # elapsed time = 0.166 

colMeans()는 벡터 또는 배열 하나에 mean()보다 빠르다. 그러나 대부분의 경우이 속도 향상은 무시할 수 있습니다. 벡터 또는 단일 열 배열에 mean()을 사용하는 것이 더 자연 스럽습니다. 그러나 진정한 속도의 악마라면 단일 열 배열 대신 colMeans()을 사용하여 수백 밀리 초의 처리 시간을 절약한다는 사실을 알면 밤에는 잘 수 있습니다.

관련 문제