2015-01-04 65 views
4

我有一個很大的數據集,我在R中分析,我對一列或信息向量感興趣。這個向量中的每個條目都有一個不同的數字(範圍從1到5)有效數字,我想對這個向量進行子集化,所以我沒有看到只有一個有效數字的數據。可以使用什麼樣的測試或功能讓R報告每個條目的有效數字的數量?我研究過signif()函數,但更多的是將數據舍入到指定的有效數字位數,而不是查詢有多少個無花果。如何確定R中有效數字的數量?

示例:假設我有這樣的矢量:
28.382
82.3
30.0003

我想刪除僅具有一個顯著位的條目。這將是條目1(值4)和條目5(值100)。我知道如何在R中對數據進行子集分類,但我不知道如何告訴R只用一個有效數字「查找」所有值。

+0

如果您將存儲的浮動物的打印表示與實際存儲的值混淆,則可能會匆匆忙忙。雖然Roland的解決方案看起來不錯,但我強烈建議您將實際報告的精度轉換爲字符串並從那裏開始工作。 –

回答

5
x <- c(4, 28.382, 120, 82.3, 100, 30.0003) 
#compare the values with result of signif 
#you need to consider floating point precision 
keep <- abs(signif(x, 1) - x) > .Machine$double.eps 
x[keep] 
#[1] 28.3820 120.0000 82.3000 30.0003 
+0

可能的錯誤(有點術語):在工程界,字符串「100」被認爲有一個sigfig,而「100.0」有四個sigfig,但是你的代碼將數值視爲相同。根據OP的值是如何創建(和表示),這可能會出現問題。也許有些函數檢查小數點的存在並適當調整檢查機制? (我看到akrun刪除了一個這樣的方法;我可能在一個新的答案中恢復它) –

+0

我的數據集非常龐大,有成千上萬的人正在進行測量並添加他們的條目,我認爲更保守的是更安全的選擇。所以即使有這樣一個精確度量的「100.0」,寫出來的答案也是足夠的。但是你說得對,在你提到的特殊情況下,這個答案不適用於sigfigs。 – pocketlizard

1

我認爲這應該等同於Rolands解決方案。

x <- c(4, 4.0, 4.00, 28.382, 120, 
     82.3, 100, 100.0, 30.0003) 
x 
ifelse(x == signif(x, 1), NA, x) 
ifelse(x == signif(x, 2), NA, x) 
ifelse(x == signif(x, 3), NA, x) 

在任何情況下,至少有給人顯著位數不正確的號碼,如「4.00」和「100.0」的情況下同樣的問題。

如上所述,解決方案的一部分是將數字視爲字符串。僅僅將數字轉換爲字符是不夠的,它們必須被讀入,這需要小心。 read.table功能組can come in handy中的colClasses參數。

xc <- c("4", "4.0", "4.00", "28.382", "120", 
     "82.3", "100", "100.0", "30.0003") 
xc 
# "4" "4.0" "4.00" "28.382" "120" "82.3" "100" "100.0" "30.0003" 
ifelse(xc == signif(as.numeric(xc), 1), NA, xc) 
# "NA" "4.0" "4.00" "28.382" "120" "82.3" "NA" "100.0" "30.0003" 

只刪除「4」和「100」。這看起來很有希望,但如果我們進一步發展,我們會發現並非所有事情都應該如此。

ifelse(xc == signif(as.numeric(xc), 2), NA, xc) 
# "NA" "4.0" "4.00" "28.382" "120" "82.3" "NA" "100.0" "30.0003" 
ifelse(xc == signif(as.numeric(xc), 3), NA, xc) 
# "NA" "4.0" "4.00" "28.382" "120" "82.3" "NA" "100.0" "30.0003" 

理由可以證明這樣

2 == "2" 
# TRUE – only what's between the quotes is compared 
2.0 == "2"; 02 == "2" 
# TRUE 
# TRUE – R removes what's considered numerically empty characters 
2 == "2.0" 
# FALSE – strings aren't modified. 
2 == as.numeric("2.0") 
# TRUE – that is, unless you explicitly request it. 

這也是值得銘記的字符串的比較是基於字母順序,即使字符串容易可以解釋爲數字。

2 < "2.0" 
# TRUE 
2 > "2.0" 
# FALSE 
"2.0" < "2.00" 
# TRUE 
sort(xc) 
# "100" "100.0" "120" "28.382" "30.0003" "4" "4.0" "4.00" "82.3" 

到目前爲止,我發現這個問題的唯一完整的解決方法是一個小黑客。它包括分離出包含小數點分隔符(「。」)的字符串,並用「1」(或任何非零數字)替換這些字符串的最後一個字符。因此將「4.0」變成「4.1」,但保持「100」原樣。這個新的矢量然後被用作比較的基礎。

xc.1 <- xc 
decimal <- grep(".", xc, fixed=TRUE) 
xc.1[decimal] <- gsub(".$", "1", xc[decimal]) 
xc.1 <- as.numeric(xc.1) 

xc 
# "4" "4.0" "4.00" "28.382" "120" "82.3" "100" "100.0" "30.0003" 
ifelse(xc.1 == signif(xc.1, 1), NA, xc) 
# "NA" "4.0" "4.00" "28.382" "120" "82.3" "NA" "100.0" "30.0003" 
ifelse(xc.1 == signif(xc.1, 2), NA, xc) 
# "NA" "NA" "4.00" "28.382" "NA" "82.3" "NA" "100.0" "30.0003" 
ifelse(xc.1 == signif(xc.1, 3), NA, xc) 
# "NA" "NA" "NA" "28.382" "NA" "NA" "NA" "100.0" "30.0003" 

如果你想實際計算有效數字的數量,可以用一個小循環來完成。

n <- 7 

# true counts 
xc.count <- vector(length=length(xc.1)) 
for (i in n:1) xc.count[xc.1 == signif(xc.1, i)] <- i 
xc.count 
# 1 2 3 5 2 3 1 4 6 

# simple counts 
x.count <- vector(length=length(x)) 
for (i in n:1) x.count[x == signif(x, i)] <- i 
x.count 
# 1 1 1 5 2 3 1 1 6 
相關問題