Ganti semua nilai tertentu dalam bingkai data


95

Memiliki kerangka data, bagaimana cara saya mengganti semua nilai tertentu di sepanjang semua baris dan kolom. Katakanlah misalnya saya ingin mengganti semua catatan kosong dengan NA's (tanpa mengetik posisi):

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

    A   B
1      12
2  xyz    
3  jkl 100

Hasil yang diharapkan:

    A   B
1  NA   12
2  xyz  NA  
3  jkl  100

Jawaban:


144

Seperti ini:

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

14
apakah ada cara untuk melakukan ini secara efisien untuk lebih dari 1 nilai !?
PikkuKatja

28
Ini tidak berfungsi untuk faktor, df[df=="xyz"]<-"abc"akan error dengan "tingkat faktor tidak valid." Apakah ada solusi yang lebih umum?
glallen

1
tidak bekerja untuk saya. Saya mencoba ini: dfSmallDiscreteCustomSalary [dfSmallDiscreteCustomSalary $ gaji == "<= 50K"] <- "49K". Masih untuk gaji unik (dfSmallDiscreteCustomSalary $) saya dapat: [1]> 50K <= 50K
Codious-JR

3
glallen ... jika Anda mencoba memodifikasi kolom faktor dengan nilai baru yang sudah menjadi faktor, mungkin ada cara yang lebih cerdas yang akan saya sarankan, tetapi Anda dapat df $ factorcolumn <- as.character ( df $ factorcolumn), lalu buat modifikasi Anda, dan akhiri dengan mengubahnya kembali menjadi faktor ... df $ factorcolumn <- as.factor (df $ factorcolumn); itu akan lengkap dengan level baru Anda dan nilai yang diinginkan.
Joshua Eric Turcotte

Menemukannya: df.na.replace (df.columns, Map ("" -> "NA")). Show. Menariknya saya tidak bisa mengganti dengan null sebagai value. Saya mendapatkan: java.lang.IllegalArgumentException: Jenis nilai yang tidak didukung java.lang.String (null). di org.apache.spark.sql.DataFrameNaFunctions.org $ apache $ spark $ sql $ DataFrameNaFunctions $$ convertToDouble (DataFrameNaFunctions.scala: 434)
sriram

35

Karena PikkuKatja dan glallen meminta solusi yang lebih umum dan saya belum bisa berkomentar, saya akan menulis jawaban. Anda dapat menggabungkan pernyataan seperti di:

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

Untuk faktor, kode zxzak sudah menghasilkan faktor:

> 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

Jika dalam masalah, saya sarankan untuk sementara menghilangkan faktor-faktor tersebut.

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

20

Berikut ini beberapa dplyropsi:

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

Bagaimana Anda akan menggunakan solusi semua kolom untuk mengganti beberapa string dengan NA di seluruh dataset?
Tea Tree

4

Kita bisa menggunakan data.table untuk mendapatkannya dengan cepat. Pertama buat df tanpa faktor,

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

Sekarang Anda bisa menggunakan

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

dan Anda dapat mengubahnya kembali menjadi data.frame

setDF(df)

Jika Anda hanya ingin menggunakan data.frame dan mempertahankan faktor itu lebih sulit, Anda perlu bekerja dengannya

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

dimana nilai adalah nama setiap kolom. Anda perlu memasukkannya dalam satu lingkaran.


2
Mengapa Anda menggunakan pustaka eksternal untuk kasus penggunaan ini? Kenapa harus loop jika ini bisa diselesaikan dengan satu baris? Bagaimana jawaban Anda menambah nilai di luar jawaban yang sudah ada? Saya tidak bermaksud untuk menjadi kasar, saya pikir saya melewatkan sesuatu, oleh karena itu pertanyaannya.
sedot

2
Jauh lebih cepat untuk kumpulan data besar. Itu menambahkan alternatif sehingga pengguna dapat memilih yang terbaik untuknya.
skan

0

Jika Anda ingin mengganti beberapa nilai dalam bingkai data, perulangan melalui semua kolom mungkin membantu.

Katakanlah Anda ingin mengganti ""dan 100:

na_codes <- c(100, "")
for (i in seq_along(df)) {
    df[[i]][df[[i]] %in% na_codes] <- NA
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.