2012-08-27 1 views
4

나는 다음과 같은 데이터 프레임이 : 나는 정상화하고 싶은내가 합으로 데이터 프레임 값을 정상화 할 수있는 방법 (퍼센트를 얻을)

이제
> str(df) 
'data.frame': 52 obs. of 3 variables: 
    $ n : int 10 20 64 108 128 144 256 320 404 512 ... 
    $ step : Factor w/ 4 levels "Step1","Step2",..: 1 1 1 1 1 1 1 1 1 1 ... 
    $ value: num 0.00178 0.000956 0.001613 0.001998 0.002975 ... 

/을에 속하는 값의 합에 의해 df$value 분할을 동일한 n ie 그래서 나는 백분율을 얻을 수있다. 이것은 효과가 없지만 내가 성취하고자하는 것을 보여줍니다.

dfa <- aggregate(x=df$value, by=list(df$n), FUN=sum) 
names(dfa)[names(dfa)=="Group.1"] <- "n"   
names(dfa)[names(dfa)=="x"] <- "value" 
df$value <- df$value/dfa[dfa$n==df$n,][[1]] 

답변

4

내가 패키지 data.table를 사용하여 다음 작품을 생각 : 여기가 DFA로 같은 N에 속하고 n 일치로 집계 된 총 dfa$value에 의해 원래의 df$value에 분할하려고 값의 합계를 미리 계산.

df <- data.table(df) 
df[,value2 := value/sum(value),by=n] 
+0

가 테이블로 변환 정말 필요한가? 그렇지 않으면 데이터 프레임으로 다시 가져올 수 있습니까? ggplot2로 플로팅하는 데 필요합니다 ... –

+3

'data.table'은'data.frame'을 확장하므로 데이터 프레임에 할 수있는 모든 작업을 데이터 테이블에 추가 할 수 있습니다. 이 작업을 수행 한 후에 데이터 프레임으로 다시 변환 할 수도 있습니다. –

1

당신이 코드의 문제는이 라인 :

df$value <- df$value/dfa[dfa$n==df$n,][[1]] 

n 일치하는 경우 각각의 인덱스를 알 길이 max(length(df),length(dfa)의 논리적 벡터를 반환 dfa$n==df$n 라인입니다. 나는 당신이 dfa$ndf$n에 맞추기 위해 그것을 사용할 수 있다고 생각하지 않습니다. base 기능을 사용

, 당신은 aggregatemerge를 사용할 수 있습니다

dfa <- aggregate(x=df$value, by=list(df$n), FUN=sum) 
names(dfa) <- c("n","sum.value") 
df2 <- merge(df,dfa,by="n",all = TRUE) 
df2$value2 <- df2$value/df2$sum.value 
+0

데이터가 큰 경우 병합 단계가 매우 느립니다. 먼저 제공 한'data.table' 솔루션이 훨씬 더 좋습니다. 그리고 OP의 관심사에 대답하기 위해, 당신은 언제나''as.data.frame'을 가진'ggplot'에 대해서''data.frame' 만 "강제로"되돌릴 수 있습니다. – Justin

+0

효율성에 대해 잘 알고 있습니다. 여러 가지 방법으로 일을하는 것이 좋지 않을 수도 있지만,이 대답은 자기 방종이라고 생각합니다. 그것은 OP의 데이터 세트가 52 행인 것처럼 보이므로 속도는 큰 관심사가 아닙니다. –

+0

fwiw,'plyr' 또한 작은 데이터 크기를위한 우아한 솔루션입니다. '도서관 (plyr); dhply (df,. (n), transform, value2 = value/sum (value))' – Justin

4

내가 ave을 사용합니다 :

set.seed(123) 
df <- data.frame(n=rep(c(2,3,6,8), each=5), value = sample(5:60, 20)) 
df$value_2 <- ave(df$value, list(df$n), FUN=function(L) L/sum(L))