2013-07-11 29 views
6

Tôi đang làm việc trong R và có một khung dữ liệu, dd_2006, với các vectơ số. Khi tôi lần đầu tiên nhập dữ liệu, tôi cần phải loại bỏ các điểm thập phân, và một số khoảng trắng từ 3 biến của tôi: SumOfCost, SumOfCases và SumOfUnits. Để làm điều đó, tôi đã sử dụng str_replace_all. Tuy nhiên, khi tôi sử dụng str_replace_all, các vectơ đã được chuyển đổi thành ký tự. Vì vậy, tôi đã sử dụng as.numeric (var) để chuyển đổi vectơ thành số, nhưng NA đã được giới thiệu, mặc dù khi tôi chạy mã bên dưới TRƯỚC KHI tôi chạy mã as.numeric, không có NA trong vectơ.Chuyển đổi ký tự thành số mà không có sự cưỡng chế NA trong R

sum(is.na(dd_2006$SumOfCost)) 
[1] 0 
sum(is.na(dd_2006$SumOfCases)) 
[1] 0 
sum(is.na(dd_2006$SumOfUnits)) 
[1] 0 

Đây là mã của tôi sau khi nhập, bắt đầu với việc xóa $ khỏi vectơ. Trong đầu ra str(dd_2006), tôi đã xóa một số biến vì lợi ích của không gian, vì vậy các cột #s trong mã str_replace_all dưới đây không khớp với kết quả tôi đã đăng ở đây (nhưng chúng có trong mã gốc):

library("stringr") 
dd_2006$SumOfCost <- str_sub(dd_2006$SumOfCost, 2,) #2=the first # after the $ 

#Removes decimal pt, zero's after, and commas 
dd_2006[ ,9] <- str_replace_all(dd_2006[ ,9], ".00", "") 
dd_2006[,9] <- str_replace_all(dd_2006[,9], ",", "") 

dd_2006[ ,10] <- str_replace_all(dd_2006[ ,10], ".00", "") 
dd_2006[ ,10] <- str_replace_all(dd_2006[,10], ",", "") 

dd_2006[ ,11] <- str_replace_all(dd_2006[ ,11], ".00", "") 
dd_2006[,11] <- str_replace_all(dd_2006[,11], ",", "") 

str(dd_2006) 
'data.frame': 12604 obs. of 14 variables: 
$ CMHSP      : Factor w/ 46 levels "Allegan","AuSable Valley",..: 1 1 1 
$ FY      : Factor w/ 1 level "2006": 1 1 1 1 1 1 1 1 1 1 ... 
$ Population    : Factor w/ 1 level "DD": 1 1 1 1 1 1 1 1 1 1 ... 
$ SumOfCases    : chr "0" "1" "0" "0" ... 
$ SumOfUnits    : chr "0" "365" "0" "0" ... 
$ SumOfCost     : chr "0" "96416" "0" "0" ... 

tôi tìm thấy câu trả lời cho một câu hỏi tương tự để khai thác here, sử dụng đoạn mã sau:

# create dummy data.frame 
d <- data.frame(char = letters[1:5], 
       fake_char = as.character(1:5), 
       fac = factor(1:5), 
       char_fac = factor(letters[1:5]), 
       num = 1:5, stringsAsFactors = FALSE) 

chúng ta hãy có một cái nhìn tại data.frame

> d 
    char fake_char fac char_fac num 
1 a   1 1  a 1 
2 b   2 2  b 2 
3 c   3 3  c 3 
4 d   4 4  d 4 
5 e   5 5  e 5 

và để chúng tôi chạy:

> sapply(d, mode) 
     char fake_char   fac char_fac   num 
"character" "character" "numeric" "numeric" "numeric" 
> sapply(d, class) 
     char fake_char   fac char_fac   num 
"character" "character" "factor" "factor" "integer" 

Bây giờ bạn có thể tự hỏi "Trường hợp bất thường ở đâu?" Vâng, tôi đã gặp phải những điều khá đặc biệt trong R, và đây không phải là điều gây nhầm lẫn nhất, nhưng nó có thể gây nhầm lẫn cho bạn, đặc biệt là nếu bạn đọc điều này trước khi lăn vào giường.

Ở đây: hai cột đầu tiên là ký tự. Tôi đã cố tình gọi 2nd_ fake_char. Phát hiện sự giống nhau của biến ký tự này với biến Dirk được tạo ra trong câu trả lời của anh ta. Nó thực sự là một vector số được chuyển đổi thành ký tự. Cột thứ 3 và thứ 4 là yếu tố và cột cuối cùng là số "hoàn toàn".

Nếu bạn sử dụng hàm chuyển đổi, bạn có thể chuyển đổi false_char thành số, chứ không phải biến char.

> transform(d, char = as.numeric(char)) 
    char fake_char fac char_fac num 
1 NA   1 1  a 1 
2 NA   2 2  b 2 
3 NA   3 3  c 3 
4 NA   4 4  d 4 
5 NA   5 5  e 5 
Warning message: 
In eval(expr, envir, enclos) : NAs introduced by coercion 
but if you do same thing on fake_char and char_fac, you'll be lucky, and get away with no NA's: 

biến đổi (d, fake_char = as.numeric (fake_char), char_fac = as.numeric (char_fac))

char fake_char fac char_fac num 
1 a   1 1  1 1 
2 b   2 2  2 2 
3 c   3 3  3 3 
4 d   4 4  4 4 
5 e   5 5  5 5 

Vì vậy, tôi đã thử đoạn code trên trong kịch bản của tôi , nhưng vẫn đến với NA (không có thông điệp cảnh báo về cưỡng chế).

#changing sumofcases, cost, and units to numeric 
dd_2006_1 <- transform(dd_2006, SumOfCases = as.numeric(SumOfCases), SumOfUnits = as.numeric(SumOfUnits), SumOfCost = as.numeric(SumOfCost)) 

> sum(is.na(dd_2006_1$SumOfCost)) 
[1] 12 
> sum(is.na(dd_2006_1$SumOfCases)) 
[1] 7 
> sum(is.na(dd_2006_1$SumOfUnits)) 
[1] 11 

Tôi cũng đã sử dụng table(dd_2006$SumOfCases) vv để xem xét các quan sát để xem có bất kỳ ký tự nào mà tôi bỏ qua trong quan sát hay không, nhưng không có bất kỳ ký tự nào. Bất kỳ suy nghĩ nào về lý do tại sao các Quốc hội đang xuất hiện và cách loại bỏ chúng?

+2

Xin lỗi, nhưng câu hỏi là gì? Câu trả lời được liên kết dường như tổng hợp mọi thứ khá tốt và không có ví dụ tái tạo về vấn đề * bạn * đang đối mặt, tôi không chắc cách người khác có thể giúp ... – A5C1D2H2I1M1N2O1R2T1

+0

Tôi đoán dữ liệu này đến từ Excel hoặc một bảng tính khác. Lần tới, xóa tất cả các định dạng trước khi bạn xuất. –

Trả lời

10

Như Anando đã chỉ ra, vấn đề ở đâu đó trong dữ liệu của bạn và chúng tôi thực sự không thể giúp bạn nhiều nếu không có ví dụ tái sản xuất.Điều đó nói rằng, đây là một đoạn mã để giúp bạn ghim xuống các bản ghi trong dữ liệu của bạn đang gây ra bạn vấn đề:

test = as.character(c(1,2,3,4,'M')) 
v = as.numeric(test) # NAs intorduced by coercion 
ix.na = is.na(v) 
which(ix.na) # row index of our problem = 5 
test[ix.na] # shows the problematic record, "M" 

Thay vì đoán là tại sao NA đang được giới thiệu, kéo ra các mẩu tin là gây ra vấn đề và giải quyết trực tiếp/cá nhân cho đến khi các Quốc hội biến mất.

CẬP NHẬT: Có vẻ như sự cố xảy ra trong cuộc gọi của bạn tới str_replace_all. Tôi không biết thư viện stringr, nhưng tôi nghĩ rằng bạn có thể thực hiện điều tương tự với gsub như thế này:

v2 = c("1.00","2.00","3.00") 
gsub("\\.00", "", v2) 

[1] "1" "2" "3" 

Tôi không hoàn toàn chắc chắn rằng điều này hoàn thành mặc dù:

sum(as.numeric(v2)!=as.numeric(gsub("\\.00", "", v2))) # Illustrate that vectors are equivalent. 

[1] 0 

Trừ khi đây đạt được một số mục đích cụ thể cho bạn, tôi khuyên bạn nên bỏ qua bước này từ quá trình tiền xử lý của bạn hoàn toàn, vì nó không xuất hiện cần thiết và dường như đang cho bạn các vấn đề.

+0

Khi tôi chạy mã đó cho SumOfUnits, tôi nhận được '> (ix.na) #row chỉ số của vấn đề NAs [1] 1098 2297 4728 5559 5592 5702 6955 8191 10517 10881 10955 > kiểm tra [ix.na] # [ 1] "" "" "" "" "" "" "" "" "" "" "" " Nhưng khi tôi nhìn vào các hàng trong tập dữ liệu gốc, có vẻ như sau: ' SumOfUnits 800.00 0,00 100,00 100,00 100,00 300,00 400,00 200,00 200,00 600,00 100.00' Vậy làm thế nào là một pro blem với dữ liệu thay vì một cái gì đó xảy ra khi tôi chạy mã 'str_replace_all'? – idemanalyst

+0

Có vẻ như bạn đã ghim sự cố xuống. Tôi không thực sự biết những gì xử lý trước các chuỗi đó hoàn thành vì bạn có thể truyền các giá trị đó đến các số chỉ tốt hoặc không có số thập phân, nhưng tôi minh họa một giải pháp thay thế bằng cách sử dụng 'gsub' trong câu trả lời cập nhật của tôi. –

+0

là vậy, cảm ơn! – idemanalyst

4

Nếu bạn muốn chuyển đổi ký tự thành số, trước tiên hãy chuyển đổi ký tự thành một yếu tố (sử dụng as.factor) và lưu/ghi đè biến hiện có. Tiếp theo chuyển đổi biến yếu tố này thành số (sử dụng as.numeric). Bạn sẽ không tạo NA theo cách này và sẽ có thể chuyển đổi tập dữ liệu bạn đã nhập thành số.

+0

as.numeric (as.factor (df $ x)) chỉ thay thế các giá trị bằng 1 và 2, chỉ mục –

Các vấn đề liên quan