2014-12-03 17 views
1

我有一個數據幀的值和數據幀中的每個值我想確定它是否在其中的任何任何的10%在其行中。我想這樣做一般,因爲我不知道我會有多少列,也不知道列的名稱。R:查找值是否在其行中任何其他值的某個百分比內

某些值爲NA,如果該行中的所有其他值都是NA,則我想返回TRUE。對於NA的實際值,我想返回FALSE。的值都是正的,但是可以爲0。

例如說我都有下列數據幀

dataDF <- data.frame(
        a = c(100, 250, NA, 700, 0), 
        b = c(105, 300, 280, NA, 0), 
        c = c(200, 400, 280, NA, 0) 
        ) 

在第一行中,我們有一個= 100,B = 105和c = 200 a和b相差在10%以內,所以我們對這兩者都是TRUE,c不在a或b的10%之內,所以會是FALSE。

在第二行中沒有值在彼此的10%之內,因此所有將是FALSE

在第三行中b和c是相等的,從而是TRUE,一個是NA如此是FALSE。

在第四行中,我們只擁有一個值,所以它返回TRUE,b,c爲FALSE

在最後一行的所有值都是一樣的,所以我們必須適用於所有

所以我的產出將是

data.frame(
      a = c(TRUE, FALSE, FALSE, TRUE, TRUE), 
      b = c(TRUE, FALSE, TRUE, FALSE, TRUE), 
      c = c(FALSE, FALSE, TRUE, FALSE, TRUE) 
     ) 

如何計算的百分比差異其實並不重要,但他們的方式我打算做那將是由平均2個的值,這樣來劃分的絕對差值無論從哪個角度來看,我都會得到相同的價值。

因此,例如,計算100和105之間的百分比差異這將是:

abs(100 - 105)/((100 + 105)/2) = 5/102.5 = 0.0488 

在這樣做的最快和最巧妙的方法任何想法,將不勝感激。

感謝

回答

1

定義一個函數的把它在你data.frame中的每一行:

fun <- function(vec) 
{ 
    n = length(vec) 

    if(all(is.na(vec))) 
    return(rep(FALSE,n)) 

    noNA = vec[!is.na(vec)] 

    if(length(unique(noNA))==1) 
    return(!is.na(vec)) 

    res = rep(FALSE, n) 

    for(i in 1:n) 
    if(any(abs(vec[i]-vec[-i])<=vec[-i]*0.1, na.rm = TRUE)) 
     res[i] = TRUE 

    res 
} 

output=data.frame(t(apply(dataDF,1,fun))) 
names(output) = names(dataDF) 
output 

給人的通緝的結果:

#  a  b  c 
#1 TRUE TRUE FALSE 
#2 FALSE FALSE FALSE 
#3 FALSE TRUE TRUE 
#4 TRUE FALSE FALSE 
#5 TRUE TRUE TRUE 
+0

謝謝上校,我已編輯上述將任何(...)四捨五入計算以檢查是否有任何列小於10%,而不僅僅是第一個。還必須將na.rm = TRUE來處理那些我們有NA並且其他列中至少有不同值的情況。它可以很好地工作,雖然有點慢,因爲我的數據幀長達100,000個行,所以必須循環每一行。如果沒有一個完美的循環來實現它,否則這將會很好。謝謝 – user1165199 2014-12-03 13:20:34

相關問題