2014-01-21 154 views
2

我有一個數據框,其中包含一些NA的數值1:4。對於每一行,我想計算值最少出現次數大於0的值的頻率(以百分比表示)。查找大於0的最小值

下面是一個示例數據框。

df = as.data.frame(rbind(c(1,2,1,2,2,2,2,1,NA,2),c(2,3,3,2,3,3,NA,2,NA,NA),c(4,1,NA,NA,NA,1,1,1,4,4),c(3,3,3,4,4,4,NA,4,3,4))) 

     V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 
    1 1 2 1 2 2 2 2 1 NA 2 
    2 2 3 3 2 3 3 NA 2 NA NA 
    3 4 1 NA NA NA 1 1 1 4 4 
    4 3 3 3 4 4 4 NA 4 3 4 

我有2點,我掙扎着。 1)找到大於0的值的最低頻率,2)將該函數應用於我的數據幀的每一行。當我開始研究這個函數時,我使用下面的代碼實現了它,但它似乎並不適用於每一行。我對value.1,value.2等的結果對於每一行都是一樣的。

Low_Freq = function(x){ 
     value.1 = sum(x==1, na.rm=TRUE) #count the number of 1's per row 
     value.2 = sum(x==2, na.rm=TRUE) #count the number of 2's per row 
     value.3 = sum(x==3, na.rm=TRUE) #count the number of 3's per row 
     value.4 = sum(x==4, na.rm=TRUE) #count the number of 4's per row 
     num.values = rowSums(!is.na(x), na.rm=TRUE) #count total number of non-NA values in each row 

     #what is the minimum frequency value greater than 0 among value.1, value.2, value.3, and value.4 for EACH row? 
     min.value.freq = min(cbind(value.1,value.2,value.3,value.4)) 

     out = min.value.freq/num.values #calculate the percentage of the minimum value for each row 
    } 

    df$Low_Freq = apply(df, 1, function(x)) 

然後我開始使用rowSums()來計算value.1,value.2,value.3和value.4。這個固定我的每一行計數value.1,value.2等問題,但是,我只好再應用功能,而無需使用應用(的)才能運行:

Low_Freq = function(x){ 
     value.1 = rowSums(x==1, na.rm=TRUE) #count the number of 1's per row 
     value.2 = rowSums(x==2, na.rm=TRUE) #count the number of 2's per row 
     value.3 = rowSums(x==3, na.rm=TRUE) #count the number of 3's per row 
     value.4 = rowSums(x==4, na.rm=TRUE) #count the number of 4's per row 
     num.values = rowSums(!is.na(x), na.rm=TRUE) #count total number of non-NA values in each row 

     #what is the minimum frequency value greater than 0 among value.1, value.2, value.3, and value.4 for EACH row? 
     min.value.freq = min(cbind(value.1,value.2,value.3,value.4)) 

     out = min.value.freq/num.values #calculate the percentage of the minimum value for each row 
    } 

    df$Low_Freq = Low_Freq(df) 

所以行爲應用於每一行似乎都發生在函數內部。這一切都很好,但是當我將我的最終計算結果作爲我的輸出時,我無法弄清楚如何確定哪一個值1,2,3,或4對於每一行具有最低的頻率。該值必須除以每行的非NA值的數量。

我想要的結果應該是這樣的:

 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 Low_Freq 
    1 1 2 1 2 2 2 2 1 NA 2 0.3333333 
    2 2 3 3 2 3 3 NA 2 NA NA 0.4285714 
    3 4 1 NA NA NA 1 1 1 4 4 0.4285714 
    4 3 3 3 4 4 4 NA 4 3 4 0.4444444 

我覺得我在圈子裏這個看似簡單的功能去。任何幫助,將不勝感激。

謝謝。

回答

3

table函數將返回出現的每個值的頻率,忽略NA值。因此,table結果的min是行中出現的值的最小頻率,並且該總和是行中的非值的數目NA

Low_Freq = function(x){ 
    tab = table(x) 
    return(min(tab)/sum(tab)) 
} 
df$Low_Freq = apply(df, 1, Low_Freq) 
df 
# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 Low_Freq 
# 1 1 2 1 2 2 2 2 1 NA 2 0.3333333 
# 2 2 3 3 2 3 3 NA 2 NA NA 0.4285714 
# 3 4 1 NA NA NA 1 1 1 4 4 0.4285714 
# 4 3 3 3 4 4 4 NA 4 3 4 0.4444444 

如果你想不使用5秒的分子,但使用它們的分母,你可以這樣做:

df = as.data.frame(rbind(c(1,2,1,2,2,2,2,1,NA,2),c(2,3,3,2,3,3,NA,2,NA,NA),c(4,1,NA,NA,NA,1,1,1,4,4),c(3,3,3,4,4,4,5,4,3,4))) 
Low_Freq = function(x){ 
    tab = table(x[x != 5]) 
    return(min(tab)/sum(!is.na(x))) 
} 
df$Low_Freq = apply(df, 1, Low_Freq) 
df 
# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 Low_Freq 
# 1 1 2 1 2 2 2 2 1 NA 2 0.3333333 
# 2 2 3 3 2 3 3 NA 2 NA NA 0.4285714 
# 3 4 1 NA NA NA 1 1 1 4 4 0.4285714 
# 4 3 3 3 4 4 4 5 4 3 4 0.4000000 
+0

謝謝你的回覆。如果我在兩行中發生了一次數字「5」,而我只想使用數字1,2,3和4的最小頻率,我該如何修改?但是這個數字除以的總數仍然應該是非NA值的數量(包括5)? – SC2

+0

@ SC2我更新了這個新功能 – josliber

+0

美麗,非常感謝! – SC2