2015-08-22 51 views
2

我試圖計算數字列的模式。不是數字的列應該有一個「NA」作爲向量中的佔位符。根據目標我也需要百分比。一些示例性數據:R - 按模式和目標計算模式和百分比

c1= c("A", "B", "C", "C", "B", "C", "C") 
c2= factor(c(1, 1, 2, 2,1,2,1), labels = c("Y","N")) 
d= as.Date(c("2015-02-01", "2015-02-03","2015-02-01","2015-02-05", "2015-02-03","2015-02-01", "2015-02-03"), format="%Y-%m-%d") 
x= c(1,1,2,3,1,2,4) 
y= c(1,2,2,6,2,3,1) 
t= c(1,0,1,1,0,0,1) 
df=data.frame(c1, c2, d, x, y,t) 
df 

    c1 c2   d x y t 
1 A Y 2015-02-01 1 1 1 
2 B Y 2015-02-03 1 2 0 
3 C N 2015-02-01 2 2 1 
4 C N 2015-02-05 3 6 1 
5 B Y 2015-02-03 1 2 0 
6 C N 2015-02-01 2 3 0 
7 C Y 2015-02-03 4 1 1 

我需要爲每個數字列的模式:

mode=as.numeric(c("NA","NA", "NA", 1,2,1)) 
mode 
[1] NA NA NA 1 2 1 

和行的百分比的具有t == 1的矢量,當在柱==模式

[1] NA NA NA 0.33 0.33 

和行的百分比的具有t == 1的矢量,當值在列!=模式

[1] NA NA NA 0.75 0.75 

我該如何計算這些向量?

我已經找到了狀態最好的是:

library(plyr) 

mode_fun <- function(x) { 
    mode0 <- names(which.max(table(x))) 
    if(is.numeric(x)) return(as.numeric(mode0)) 
    mode0 
} 
kdf_mode=apply(kdf,2, numcolwise(mode_fun)) 

但是,如果有任何非數字列它給出了一個錯誤。

+0

非常感謝! – ElinaJ

+0

這太複雜了,我不得不考慮它......請在你的答案下看到評論。非常感謝你的幫助! – ElinaJ

+0

更新了帖子 – akrun

回答

1

我們可以使用sapply來循環'df'列,應用mode_fun來獲得輸出vector('v1')。我們使用if/else條件爲非數字列返回NA

v1 <- unname(sapply(df, function(x) if(!is.numeric(x)) NA else mode_fun(x))) 
v1 
#[1] NA NA NA 1 2 1 

對於第二種情況(我想我們不需要第6列,即「T​​」)。我們通過sapply循環訪問'df'的列,使用if/else條件。在else條件中,我們比較mode值是否等於列值(mode_fun(x)==x))。我們使用&來獲得等於mode的值的邏輯索引,其對應於t==1。獲取sum併除以sum(v1)

unname(sapply(df[-6], function(x) if(!is.numeric(x)) { 
      NA 
      } else { 
       v1 <- mode_fun(x)==x 
       sum(v1 & t==1)/sum(v1) 
    })) 
#[1]  NA  NA  NA 0.3333333 0.3333333 

對於第三個,我們改變的條件獲得其中列不等於mode邏輯索引。和前面的情況一樣。

unname(sapply(df[-6], function(x) if(!is.numeric(x)){ 
     NA 
     } else { 
       v1 <- mode_fun(x)!=x 
       sum(v1 & t==1)/sum(v1) 
    })) 
#[1] NA NA NA 0.75 0.75 

後,我們計算出 'V1',這也可以不與sapply循環完成。我們創建了一個邏輯索引,其中列class是'數字',列名不是't'('indx')。

indx <- sapply(df, is.numeric) & names(df)!='t' 

我們子集 'DF',並根據 'INDX'(df[indx]v1[indx]) 'V1',通過使用col複製vector使長度。 col給出df[indx]中列的數字索引。然後我們檢查子集數據集是否等於vector來給出一個邏輯矩陣。

indx1 <- df[indx]==v1[indx][col(df[indx])] 

正如在前面的代碼中,我們使用&檢查在 'indx1' 的TRUE值是否還對應於「噸== 1個. Do colSums , divide by the colSums of 'indx1', and concatenate (Ç) with the的NA`元素 'V1'

unname(c(v1[is.na(v1)], colSums(indx1& t==1)/colSums(indx1))) 
#[1]  NA  NA  NA 0.3333333 0.3333333 

同樣,我們可以通過改變創造條件「indx2」,然後做colSums像以前那樣

indx2 <- df[indx]!=v1[indx][col(df[indx])] 
unname(c(v1[is.na(v1)], colSums(indx2& t==1)/colSums(indx2))) 
#[1] NA NA NA 0.75 0.75 
+0

對不起,我在示例中輸入了錯誤的數字,0.66(v1 [4])應該是0.33。這是如何:模式每列計算(現在工作正常!)。那麼對於那些值等於模式的單元格,我們計算也有t == 1的百分比。例如,在第x列中,三個值(第1,2和5行)等於模式(colx爲1),但僅在第nr行中,col中的值爲1(對於第2行和第5行,t是0)。所以這就是爲什麼v1中的第四個值應該是1/3 = 0.33。類似地,對於v2,我們正在查看哪些!=模式的值以及它們中有多少具有t == 1,因此我們得到0.75。 – ElinaJ

+1

非常感謝!我沉默了很長時間,因爲在我的真實數據中,你的代碼只給出了NA:s,儘管使用示例數據它工作得很好。我花了一段時間才意識到在阻止求和的數列中有NA:s。我添加了sum(mode_fun(x)== x,na.rm = TRUE),現在沒問題了!非常感謝! – ElinaJ

+0

@ElinaJ感謝您的反饋。 「NA」值肯定會造成問題。 – akrun