2017-02-13 77 views
0

我想測試一個矩陣的和的總和是否爲0或1.這些和是浮點數,所以與==的直接比較不起作用。比較多於一個整數的浮點數

下面是一個例子:

# Sample matrix 
mat <- matrix(rnorm(50), nrow = 5) 

# Choose some row to sum to 1. I will not know in advance which rows these are 
sum.to.1 <- sample(1:5, 3) 

mat.normalized <- mat 

# Some rows sum to 1 
mat.normalized[sum.to.1, ] <- mat[sum.to.1, ]/rowSums(mat[sum.to.1, ]) 

# Remaining rows sum to 0 
mat.normalized[-sum.to.1, ] <- mat[-sum.to.1, ] - rowMeans(mat[-sum.to.1, ]) 

rowSums(mat.normalized) # very close, but not exactly, 1 or 0 

# I want something like this: 
# all(rowSums(mat.normalized) %in% c(0, 1)) 

如果我只是測試行是否相加1,或者如果我知道這行會事先爲0,我會用all.equal。但有些行將總和爲0,我不知道先驗哪些行將是。

我也不能使用round(我認爲),因爲無論它們有多接近,所有的行都會舍入到1或0。

任何想法?似乎應該有一些簡單的事情,但我無法弄清楚。

+1

你可以測試是否有0/1的絕對差值小於閾值 – Cath

+2

'輪(rowSums(mat.normalized),地板(-log10($。機double.eps)))' – Roland

回答

2

有可能是一個更有說服力的答案,但你可以使用sapplyall.equal這樣的2回合。

# get the sums 
mySums <- rowSums(mat.normalized) 

# run through values twice. Check for equal to 1, equal to 0, then sum the results 
all(sapply(mySums, function(i) isTRUE(all.equal(i, 1))) + 
    sapply(mySums, function(i) isTRUE(all.equal(i, 0))) == 1) 
[1] TRUE 

我加了== 1因爲+會返回一個數字矢量和all抱怨這一點。正如@ cath的評論暗示的那樣,最後可以避開== 1。一個這樣的嘗試是使用Reduce

all(Reduce("|", sapply(mySums, function(i) isTRUE(all.equal(i, 1))), 
       sapply(mySums, function(i) isTRUE(all.equal(i, 0))))) 

mapply

all(mapply("|", sapply(mySums, function(i) isTRUE(all.equal(i, 1))), 
      sapply(mySums, function(i) isTRUE(all.equal(i, 0))))) 
+1

好點,我會添加第二個選項。我將「sapply」輸出相加,產生一個數字向量。 'all'將在一個數字向量上工作,但會以警告的方式投訴。例如,嘗試'all(1)'。 – lmo

+0

我在@羅蘭德的回答中,在上面的評論中,但這同樣好,謝謝。 –