แทนที่ค่าเฉพาะทั้งหมดในกรอบข้อมูล


95

มีกรอบข้อมูลฉันจะเปลี่ยนค่าเฉพาะทั้งหมดในแถวและคอลัมน์ทั้งหมดได้อย่างไร ตัวอย่างเช่นฉันต้องการแทนที่ระเบียนว่างทั้งหมดด้วยNA's (โดยไม่ต้องพิมพ์ตำแหน่ง):

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

    A   B
1      12
2  xyz    
3  jkl 100

ผลลัพธ์ที่คาดหวัง:

    A   B
1  NA   12
2  xyz  NA  
3  jkl  100

คำตอบ:


144

แบบนี้:

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

14
มีวิธีทำอย่างไรให้มีประสิทธิภาพมากกว่า 1 ค่า!?
PikkuKatja

28
สิ่งนี้ใช้ไม่ได้กับปัจจัยต่างๆdf[df=="xyz"]<-"abc"จะเกิดข้อผิดพลาดกับ "ระดับปัจจัยที่ไม่ถูกต้อง" มีวิธีแก้ปัญหาทั่วไปมากกว่านี้หรือไม่?
glallen

1
ไม่ได้ผลสำหรับฉัน ฉันลองสิ่งนี้: dfSmallDiscreteCustomSalary [dfSmallDiscreteCustomSalary $ เงินเดือน == "<= 50K"] <- "49K" ยังคงเป็นเอกลักษณ์ (dfSmallDiscreteCustomSalary $ เงินเดือน) ฉันได้รับ: [1]> 50K <= 50K
Codious-JR

3
glallen ... หากคุณกำลังพยายามแก้ไขคอลัมน์ปัจจัยด้วยค่าใหม่ที่เป็นปัจจัยอยู่แล้วอาจมีวิธีที่ชาญฉลาดกว่าที่ฉันกำลังจะแนะนำ แต่คุณสามารถ df $ factorcolumn <- as.character ( df $ factorcolumn) จากนั้นทำการแก้ไขของคุณและปิดท้ายด้วยการเปลี่ยนกลับเป็นแฟคเตอร์อีกครั้ง ... df $ factorcolumn <- as.factor (df $ factorcolumn); มันจะสมบูรณ์ด้วยระดับใหม่และมูลค่าที่คุณต้องการ
Joshua Eric Turcotte

ค้นพบ: df.na.replace (df.columns, Map ("" -> "NA")) แสดง ที่น่าสนใจคือฉันไม่สามารถแทนที่ด้วย null เป็นค่าได้ ฉันได้รับ: java.lang.IllegalArgumentException: ประเภทค่าที่ไม่รองรับ java.lang.String (null) ที่ org.apache.spark.sql.DataFrameNaFunctions.org $ apache $ spark $ sql $ DataFrameNaFunctions $$ convertToDouble (DataFrameNaFunctions.scala: 434)
sriram

35

เนื่องจาก PikkuKatja และ glallen ขอวิธีแก้ปัญหาทั่วไปมากขึ้นและฉันยังไม่สามารถแสดงความคิดเห็นได้ฉันจะเขียนคำตอบ คุณสามารถรวมคำสั่งดังต่อไปนี้:

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

สำหรับปัจจัยรหัสของ zxzak ให้ปัจจัยอยู่แล้ว:

> 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

หากมีปัญหาฉันขอแนะนำให้ลดปัจจัยชั่วคราว

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

20

นี่คือสองdplyrตัวเลือก:

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'))

คุณจะใช้โซลูชันคอลัมน์ทั้งหมดเพื่อแทนที่หลายสตริงโดย NAs ในชุดข้อมูลทั้งหมดได้อย่างไร
Tea Tree

4

เราสามารถใช้ data.table เพื่อรับมันได้อย่างรวดเร็ว ก่อนอื่นให้สร้าง df โดยไม่มีปัจจัย

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

ตอนนี้คุณสามารถใช้

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

และคุณสามารถแปลงกลับเป็น data.frame

setDF(df)

หากคุณต้องการใช้ data.frame และเก็บปัจจัยไว้เท่านั้นมันยากกว่าคุณต้องใช้งาน

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

โดยที่ค่าคือชื่อของทุกคอลัมน์ คุณต้องใส่ในลูป


2
เหตุใดคุณจึงใช้ไลบรารีภายนอกสำหรับกรณีการใช้งานนี้ ทำไมต้องวนซ้ำถ้าสิ่งนี้สามารถแก้ไขได้ด้วยบรรทัดเดียว? คำตอบของคุณเพิ่มมูลค่านอกเหนือจากคำตอบที่มีอยู่แล้วอย่างไร ฉันไม่ได้ตั้งใจที่จะรุนแรงฉันคิดว่าฉันขาดอะไรบางอย่างดังนั้นคำถาม
sedot

2
เร็วกว่ามากสำหรับชุดข้อมูลขนาดใหญ่ เป็นการเพิ่มทางเลือกเพื่อให้ผู้ใช้สามารถเลือกสิ่งที่ดีที่สุดสำหรับเขาได้
skan

0

หากคุณต้องการแทนที่ค่าหลายค่าในกรอบข้อมูลการวนซ้ำคอลัมน์ทั้งหมดอาจช่วยได้

สมมติว่าคุณต้องการแทนที่""และ100:

na_codes <- c(100, "")
for (i in seq_along(df)) {
    df[[i]][df[[i]] %in% na_codes] <- NA
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.