2011-08-08 5 views
7

R 데이터 프레임이 있고 다른 컬럼에서 하나의 컬럼을 뺍니다. $ 연산자를 사용하여 열을 추출하지만 열의 클래스가 'factor'이고 R이 요인에 대한 산술 연산을 수행하지 않습니다. 이것을 수행하는 특별한 기능이 있습니까?R 요소에 대한 산술 연산

+2

R의 요소는 일반적으로 범주 형 (또는 서수 형) 데이터를 의미합니다. 범주 형 데이터에 대해 산술을 어떻게 정의합니까? – Andrie

+0

Andrie가 말했듯이, 당신은하지 않습니다. –

답변

20

실제로 사용하는 요소의 수준을 원한다면 자신의 이익을 위해 뭔가 잘못되거나 너무 영리한 행동을하고있는 것입니다.

당신이해야하는 요인의 수준에 저장된 번호를 포함하는 요소 인 경우에, 당신은 as.numeric(as.character(...))를 사용하여 첫 번째를 숫자를 강요 할 :

dat <- data.frame(f=as.character(runif(10))) 

당신은 요소의 인덱스에 접근 사이의 차이를 볼 수 있습니다 여기 요인 내용을 할당 :

> as.numeric(dat$f) 
[1] 9 7 2 1 4 6 5 3 10 8 
> as.numeric(as.character(dat$f)) 
[1] 0.6369432 0.4455214 0.1204000 0.0336245 0.2731787 0.4219241 0.2910194 
[8] 0.1868443 0.9443593 0.5784658 

타이밍 대에만 수준에 대한 변환이이 수준은 각 요소에 고유하지 않은 경우 더 빠른 보여 않는 다른 방법 :

dat <- data.frame(f = sample(as.character(runif(10)),10^4,replace=TRUE)) 
library(microbenchmark) 
microbenchmark(
    as.numeric(as.character(dat$f)), 
    as.numeric(levels(dat$f))[dat$f] , 
    as.numeric(levels(dat$f)[dat$f]), 
    times=50 
) 

           expr  min  lq median  uq  max 
1 as.numeric(as.character(dat$f)) 7835865 7869228 7919699 7998399 9576694 
2 as.numeric(levels(dat$f))[dat$f] 237814 242947 255778 270321 371263 
3 as.numeric(levels(dat$f)[dat$f]) 7817045 7905156 7964610 8121583 9297819 

따라서 length(levels(dat$f)) < length(dat$f) 인 경우 상당한 속도 향상을 위해 as.numeric(levels(dat$f))[dat$f]을 사용하십시오. 먼저 데이터 당기는하고 어떻게 당신은 두 번 확인해야

dat <- data.frame(f = as.character(runif(10^4))) 
library(microbenchmark) 
microbenchmark(
    as.numeric(as.character(dat$f)), 
    as.numeric(levels(dat$f))[dat$f] , 
    as.numeric(levels(dat$f)[dat$f]), 
    times=50 
) 

           expr  min  lq median  uq  max 
1 as.numeric(as.character(dat$f)) 7986423 8036895 8101480 8202850 12522842 
2 as.numeric(levels(dat$f))[dat$f] 7815335 7866661 7949640 8102764 15809456 
3 as.numeric(levels(dat$f)[dat$f]) 7989845 8040316 8122012 8330312 10420161 
+0

+1은 제가하려고했던 점을 보여줍니다. –

+0

R은 인수 분해하기 전에 정렬하는 것이 현명하지만, 전체 숫자이면이 문제는 부적합합니다. –

+2

@Brandon : 누군가가'relevel'을 사용하지 않았거나 정수 시퀀스가 ​​연속적이지 않다면 말입니다. 레벨 인덱스가 레벨 내용과 같다고 가정하면 위험한 가정으로 간주됩니다. –

3

자신 만의 연산자를 정의 할 수 있습니다 (? Arith 참조). 그룹 제네릭이 없으면 자신 만의 이진 연산자를 정의 할 수 있습니다. % operator % :

+3

고양이 - 마우스 = 배고픈 고양이? – Tommy

1

숫자 인수로 변환해야합니다.

a <- factor(c(5,6,5)) 
b <- factor(c(3,2,1)) 
df <- data.frame(a, b) 

# WRONG: Factors can't be subtracted. 
df$a - df$b 

# CORRECT: Get the levels and substract 
as.numeric(levels(df$a)[df$a]) - as.numeric(levels(df$b)[df$b]) 
+1

-1 이것은 a) 귀하의 요소가 주문되었으며 b) 데이터가 구간 스케일 된 것으로 가정합니다. 이 경우 데이터가 처음부터 요인에 있지 않아야합니다. – Andrie

+0

+1 이것은 다른 솔루션 중 하나에서 주어진 as.numeric (as.character())보다 요인을 변환하는 더 좋은 방법이므로 +1하십시오. –

+0

Andrie : 벡터가 정렬되지 않은 경우 빼기가 의미있는 해석을합니까 (부여 된 교차 집합을 원할 수도 있음)? 데이터 가져 오기에 문제가있어 데이터가 처음에 인수 분해 된 것으로 의심됩니다. 여러 번 나에게 일어난 일입니다. 그런 다음 올바른 방법은 데이터를 제거하고 가져 오기를 수정하는 것입니다. –

3

: length(levels(dat$f))length(dat$f) 거의 같은 경우

는 더 속도 이득이 없습니다. 이것들이 정말로 숫자 열인 경우 R은이를 인식해야합니다 (Excel이 때때로 엉망이됩니다). 어느 쪽이든, 열에 다른 바람직하지 않은 요소가 있기 때문에 요인으로 강제 될 수 있습니다. 지금까지받은 응답에는 as.numeric()이 레벨 번호 만 반환한다는 언급이 없습니다. 즉, 요소로 변환 된 실제 숫자가 아니라 각 요소와 연관된 수준 번호에 대한 연산을 수행하지 않는다는 의미입니다.