2013-08-23 97 views
0

使用示例數據框:數值和處理缺失值

df <- structure(list(
    KY27PHY1 = c("4", "5", "5", "4", "-", "4", "2","3", "5", "-", "4", "3", "3", "5", "5"), 
    KY27PHY2 = c("4", "4","4", "4", "-", "5", "2", "3", "5", "-", "5", "3", "3", "5", "5"), 
    KY27PHY3 = c("5", "4", "4", "4", "-", "5", "1", "4", "5","-", "4", "3", "3", "5", "5")), 
       .Names = c("KY27PHY1", "KY27PHY2","KY27PHY3"), 
       row.names = 197:211, 
       class = "data.frame") 

我一直在使用下面的代碼將值轉換爲數字:

df$KY27PHY1<-as.numeric(df$KY27PHY1) 
df$KY27PHY2<-as.numeric(df$KY27PHY2) 
df$KY27PHY3<-as.numeric(df$KY27PHY3) 

既然我已經遺漏值在df數據幀中,我總是收到警告信息:

Warning message: 
NAs introduced by coercion 

我認爲這不是問題,但我只是wa對我如何改進代碼提出了一些建議,所以我沒有得到這個消息。

另外,我怎麼能一次做所有的列(由名稱指定)?

非常感謝提前。

+0

這真的很有用@ flodel - 我不知道那段代碼。 –

+0

那麼,我會給它一個答案,然後...如果你願意接受一個。 – flodel

回答

0

您可以使用sapply一次完成所有這些操作,但您最終將獲得matrix,因此您必須換回as.data.frame才能轉換回來。警告只是爲了告訴您,原始數據中的字符無法與數字匹配,因此被替換爲NA。在你的情況下,這些字符是"-"。爲了確保警告不打印,使用suppressWarnings

suppressWarnings(as.data.frame(sapply(df,as.numeric))) 
    KY27PHY1 KY27PHY2 KY27PHY3 
1   4  4  5 
2   5  4  4 
3   5  4  4 
4   4  4  4 
5  NA  NA  NA 
6   4  5  5 
7   2  2  1 
8   3  3  4 
9   5  5  5 
10  NA  NA  NA 
11  4  5  4 
12  3  3  3 
13  3  3  3 
14  5  5  5 
15  5  5  5 
1

data.table是超級快,你應該儘快你data.frames工作中使用它。對於你的問題,這將是:

library(data.table) 
dt = as.data.table(df) 
dt[,lapply(.SD,as.numeric)] 
    KY27PHY1 KY27PHY2 KY27PHY3 
1:  4  4  5 
2:  5  4  4 
3:  5  4  4 
4:  4  4  4 
5:  NA  NA  NA 
6:  4  5  5 
7:  2  2  1 
8:  3  3  4 
9:  5  5  5 
10:  NA  NA  NA 
11:  4  5  4 
12:  3  3  3 
13:  3  3  3 
14:  5  5  5 
15:  5  5  5 

當然也可以得到一些警告爲「 - 」不能轉換爲數字

2

我看到兩種可能性:

  1. 不太可能的一個是您在R中構建了data.frame。然後,只需更改代碼以首先創建整數向量,或者將-替換爲NA,這樣as.numeric轉換就不會發生抱怨。

  2. 您的data.frame更可能來自R之外,您可能會用read.tableread.csv函數之一讀取它。然後,只需將na.strings = "-"添加到您的電話中,R就會知道這些-應被理解爲NA。另外,如果這些列中沒有其他奇怪的項目,那麼在這些函數中調用的type.convert函數將自動檢測到這些列是充滿整數的列,並將它們存儲爲這樣。

0

我寫了一個小功能一定時間回處理在data.frame使某些值NA和使用type.convert將輸出轉換,因爲如果你使用過read.table與指定na.strings

這裏的功能:

makemeNA <- function(mydf, NAStrings, fixed = TRUE) { 
    dfname <- deparse(substitute(mydf)) 
    if (!isTRUE(fixed)) { 
    mydf <- data.frame(lapply(mydf, function(x) gsub(NAStrings, "", x))) 
    NAStrings <- "" 
    } 
    mydf <- data.frame(lapply(mydf, function(x) type.convert(
    as.character(x), na.strings = NAStrings))) 
    mydf 
} 

這是在使用中:

makemeNA(df, "-") 
# KY27PHY1 KY27PHY2 KY27PHY3 
# 1   4  4  5 
# 2   5  4  4 
# 3   5  4  4 
# 4   4  4  4 
# 5  NA  NA  NA 
# 6   4  5  5 
# 7   2  2  1 
# 8   3  3  4 
# 9   5  5  5 
# 10  NA  NA  NA 
# 11  4  5  4 
# 12  3  3  3 
# 13  3  3  3 
# 14  5  5  5 
# 15  5  5  5 

您可以從str ucture,我們現在有數字輸出中看到。

str(makemeNA(df, "-")) 
# 'data.frame': 15 obs. of 3 variables: 
# $ KY27PHY1: int 4 5 5 4 NA 4 2 3 5 NA ... 
# $ KY27PHY2: int 4 4 4 4 NA 5 2 3 5 NA ... 
# $ KY27PHY3: int 5 4 4 4 NA 5 1 4 5 NA ... 

na.strings,所述NAStringsmakemeNA複數。在這裏,我們將一個破折號和值「1」寫入NA

str(makemeNA(df, c("-", 1))) 
# 'data.frame': 15 obs. of 3 variables: 
# $ KY27PHY1: int 4 5 5 4 NA 4 2 3 5 NA ... 
# $ KY27PHY2: int 4 4 4 4 NA 5 2 3 5 NA ... 
# $ KY27PHY3: int 5 4 4 4 NA 5 NA 4 5 NA ... 

您還可以使用正則表達式來設置值NA,如下:

df1 <- data.frame(A = c(1, 2, "-", "not applicable", 5), 
       B = c("not available", 1, 2, 3, 4), 
       C = c("-", letters[1:4])) 

請與 「不是」 或任何價值 「 - 」 到NA

makemeNA(df1, "not.*|-", fixed = FALSE) 
# A B C 
# 1 1 NA <NA> 
# 2 2 1 a 
# 3 NA 2 b 
# 4 NA 3 c 
# 5 5 4 d 
str(makemeNA(df1, "not.*|-", fixed = FALSE)) 
# 'data.frame': 5 obs. of 3 variables: 
# $ A: int 1 2 NA NA 5 
# $ B: int NA 1 2 3 4 
# $ C: Factor w/ 4 levels "a","b","c","d": NA 1 2 3 4