Thay thế tất cả các giá trị cụ thể trong khung dữ liệu


88

Có khung dữ liệu, làm cách nào để thay thế tất cả các giá trị cụ thể dọc theo tất cả các hàng và cột. Ví dụ, tôi muốn thay thế tất cả các bản ghi trống bằng NA's (mà không cần nhập vị trí):

df <- data.frame(list(A=c("", "xyz", "jkl"), B=c(12, "", 100)))

    A   B
1      12
2  xyz    
3  jkl 100

Kết quả mong đợi:

    A   B
1  NA   12
2  xyz  NA  
3  jkl  100

Câu trả lời:


138

Như thế này:

> df[df==""]<-NA
> df
     A    B
1 <NA>   12
2  xyz <NA>
3  jkl  100

14
có cách nào để làm điều này hiệu quả cho nhiều hơn 1 giá trị không !?
PikkuKatja

28
Điều này không hiệu quả với các yếu tố, df[df=="xyz"]<-"abc"sẽ xảy ra lỗi với "cấp độ yếu tố không hợp lệ". Có một giải pháp tổng quát hơn?
glallen

1
không làm việc cho tôi. Tôi đã thử điều này: dfSmallDiscreteCustomSalary [dfSmallDiscreteCustomSalary $ lương == "<= 50K"] <- "49K". Vẫn là duy nhất (dfSmallDiscreteCustomSalary $ lương) tôi nhận được: [1]> 50K <= 50K
Codious-JR

3
glallen ... nếu bạn đang cố gắng sửa đổi cột nhân tố với một giá trị mới đã là một nhân tố, có lẽ có nhiều cách thông minh hơn mà tôi sắp đề xuất, nhưng bạn có thể df $ factorcolumn <- as.character ( df $ factorcolumn), sau đó thực hiện sửa đổi của bạn và kết thúc bằng cách chuyển nó trở lại thành nhân tố một lần nữa ... df $ factorcolumn <- as.factor (df $ factorcolumn); nó sẽ hoàn chỉnh với cấp độ mới và giá trị mong muốn của bạn.
Joshua Eric Turcotte

Đã tìm ra: df.na.replace (df.columns, Map ("" -> "NA")). Hiển thị. Điều thú vị là tôi không thể thay thế bằng giá trị null. Tôi nhận được: java.lang.IllegalArgumentException: Loại giá trị không được hỗ trợ java.lang.String (null). tại org.apache.spark.sql.DataFrameNaFunctions.org $ apache $ spark $ sql $ DataFrameNaFunctions $$ convertToDouble (DataFrameNaFunctions.scala: 434)
Sriram

34

Vì PikkuKatja và glallen đã yêu cầu một giải pháp chung hơn và tôi chưa thể bình luận nên tôi sẽ viết câu trả lời. Bạn có thể kết hợp các câu lệnh như trong:

> df[df=="" | df==12] <- NA
> df
     A    B
1  <NA> <NA>
2  xyz  <NA>
3  jkl  100

Đối với các yếu tố, mã của zxzak đã mang lại các yếu tố:

> df <- data.frame(list(A=c("","xyz","jkl"), B=c(12,"",100)))
> str(df)
'data.frame':   3 obs. of  2 variables:
 $ A: Factor w/ 3 levels "","jkl","xyz": 1 3 2
 $ B: Factor w/ 3 levels "","100","12": 3 1 2

Nếu gặp khó khăn, tôi khuyên bạn nên tạm thời loại bỏ các yếu tố.

df[] <- lapply(df, as.character)

18

Dưới đây là một số dplyrtùy chọn:

library(dplyr)

# all columns:
df %>% 
  mutate_all(~na_if(., ''))

# specific column types:
df %>% 
  mutate_if(is.factor, ~na_if(., ''))

# specific columns:  
df %>% 
  mutate_at(vars(A, B), ~na_if(., ''))

# or:
df %>% 
  mutate(A = replace(A, A == '', NA))

# replace can be used if you want something other than NA:
df %>% 
  mutate(A = as.character(A)) %>% 
  mutate(A = replace(A, A == '', 'used to be empty'))

Làm thế nào bạn sẽ sử dụng giải pháp tất cả các cột để thay thế một số chuỗi bằng NA trong toàn bộ tập dữ liệu?
Tea Tree

4

Chúng ta có thể sử dụng data.table để lấy nó một cách nhanh chóng. Đầu tiên hãy tạo df mà không có yếu tố,

df <- data.frame(list(A=c("","xyz","jkl"), B=c(12,"",100)), stringsAsFactors=F)

Bây giờ bạn có thể sử dụng

setDT(df)
for (jj in 1:ncol(df)) set(df, i = which(df[[jj]]==""), j = jj, v = NA)

và bạn có thể chuyển đổi nó trở lại data.frame

setDF(df)

Nếu bạn chỉ muốn sử dụng data.frame và giữ các yếu tố thì khó hơn, bạn cần phải làm việc với

levels(df$value)[levels(df$value)==""] <- NA

trong đó giá trị là tên của mọi cột. Bạn cần phải chèn nó vào một vòng lặp.


2
Tại sao bạn sử dụng thư viện bên ngoài cho trường hợp sử dụng này? Tại sao một vòng lặp nếu điều này có thể được giải quyết bằng một dòng? Làm thế nào để câu trả lời của bạn thêm giá trị ngoài những câu trả lời đã có? Tôi không có ý định gay gắt, tôi nghĩ rằng tôi đang thiếu một cái gì đó, do đó các câu hỏi.
sedot

2
Nó nhanh hơn nhiều đối với các bộ dữ liệu lớn. Nó thêm một giải pháp thay thế để người dùng có thể chọn tốt nhất cho mình.
skan

0

Nếu bạn muốn thay thế nhiều giá trị trong khung dữ liệu, việc lặp qua tất cả các cột có thể hữu ích.

Giả sử bạn muốn thay thế ""100:

na_codes <- c(100, "")
for (i in seq_along(df)) {
    df[[i]][df[[i]] %in% na_codes] <- NA
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.