2014-01-22 32 views
0

我正在使用以下函數,grp與data.table進行彙總並且遇到問題。因子等級訂單在與data.table聚合後修改

問題是因子變量fc_x的等級的順序在聚合後不以相同順序保持不變。 我的功能有問題,還是這個「正常」,這意味着它有一個解釋?

grp <- function(x) { 
    percentage = as.numeric(table(x)/length(x)) 
    list(x = factor(levels(x)), 
     percentage = percentage, 
     label = paste0(round(as.numeric(table(x)/length(x), 0) * 100), "%") 
) 
} 

set.seed(123) 
DT <- data.table(x = rnorm(100, 100, 50), fac = factor(letters[1:10])) 
DT$fc_x <- cut(DT$x, breaks = c(0, 50, 100, 10e5), right = T, 
      labels = c("0-50", "51-100", "+100")) 

str(DT) 
# Classes ‘data.table’ and 'data.frame': 100 obs. of 3 variables: 
# $ x : num 90.7 59.4 18 125.4 187.7 ... 
# $ fac : Factor w/ 10 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10 ... 
# $ fc_x: Factor w/ 3 levels "0-50","51-100",..: 2 2 1 3 3 3 3 3 1 1 ... 

levels(DT$fc_x) 
# [1] "0-50" "51-100" "+100" 

AGG <- DT[, grp(fc_x), by=fac] 

levels(AGG$x) 
# [1] "+100" "0-50" "51-100" 

EDIT

改變 「100」 爲 「1000」 提供了類似的結果

DT <- data.table(x = rnorm(100, 100, 50), fac = factor(letters[1:10])) 
DT$fc_x <- cut(DT$x, breaks = c(0, 50, 100, 10e5), right = T, 
       labels = c("0-50", "51-100", "1000")) 

levels(DT$fc_x) 
# [1] "0-50" "51-100" "1000" 

AGG <- DT[, grp(fc_x), by=fac] 
levels(AGG$x) 
# [1] "0-50" "1000" "51-100" 

在切割()語句中使用有序= TRUE提供了相同的結果

DT <- data.table(x = rnorm(100, 100, 50), fac = factor(letters[1:10])) 
DT$fc_x <- cut(DT$x, breaks = c(0, 50, 100, 10e5), right = T, ordered = T, 
       labels = c("0-50", "51-100", "1000")) 

levels(DT$fc_x) 
# [1] "0-50" "51-100" "1000" 

AGG <- DT[, grp(fc_x), by=fac] 
levels(AGG$x) 
# [1] "0-50" "1000" "51-100" 
+1

1.我認爲你的意思是'right = T'在'cut'語句中。第三種可能性是它是無意識的,也就是一個錯誤。 –

+0

1.當然。我修改了它,仍然得到相同的結果。 – marbel

+0

對,我並不是說這是問題,只是你在代碼中有一個錯字(可能會改變某個數字所屬的類別,但不會改變問題的性質)。 –

回答

3

我認爲這個問題是當你在你的函數中定義了x沒有提供標籤,所以它只是按字母順序放置因子水平,所以我認爲你只需要添加標籤到你的功能。

DT$fc_x <- cut(DT$x, breaks = c(0, 50, 100, 10e5), rigth = T, 
labels = c("0-50", "51-100", "+100")) 

factor(levels(DT$fc_x)) 
[1] 0-50 51-100 +100 
Levels: 0-50 +100 51-100 

factor(levels(DT$fc_x), labels = c("0-50", "51-100", "100+")) 
[1] 0-50 +100 51-100 
Levels: 0-50 51-100 +100 


grp <- function(x) { 
    percentage = as.numeric(table(x)/length(x)) 
    list(
     x = factor(levels(x), labels = levels(x)), 
     percentage = percentage, 
     label = paste0(round(as.numeric(table(x)/length(x), 0) * 100), "%") 
) 
} 

DT <- data.table(x = rnorm(100, 100, 50), fac = factor(letters[1:10])) 

DT$fc_x <- cut(DT$x, breaks = c(0, 50, 100, 10e5), rigth = T, 
       labels = c("0-50", "51-100", "+100")) 
AGG <- DT[, grp(fc_x), by=fac] 
levels(AGG$x) 
[1] "0-50" "51-100" "100+" 
+0

對不起,我的事先評論,這是不正確的。問題確實是'grp'中的因素創造。 –

+0

沒問題。謝謝。 –

+0

是不是硬編碼grp函數的級別? – marbel

0

使用GRP功能的修改後的版本與真實數據集後,水平不錯,但weren't聚集後相匹配的實際值。

我想出了這個,我相信更簡單的解決方案將名稱傳遞給表結果。 如果我不使用as.numeric(表(...))我保留名稱。

謝謝你的幫助馬特,馬修。我會離開接受你的答案,因爲它是有幫助的。

grp <- function(x) { 
    percentage = data.frame(table(x)/length(x)) 
    list(x = factor(percentage[[1]]), 
     percentage = percentage[[2]], 
     label = paste0(round(as.numeric(percentage[[2]], 2) * 100) , "%") 
) 
}