Bir veri çerçevesindeki tüm belirli değerleri değiştirin


96

Bir veri çerçevesine sahip olarak, tüm satırlar ve sütunlar boyunca tüm belirli değerleri değiştirmeye nasıl devam edebilirim. Örneğin, tüm boş kayıtları NA's ile değiştirmek istiyorum (konumları yazmadan):

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

    A   B
1      12
2  xyz    
3  jkl 100

Beklenen Sonuç:

    A   B
1  NA   12
2  xyz  NA  
3  jkl  100

Yanıtlar:


145

Bunun gibi:

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

14
1 değerden fazla bunu verimli bir şekilde yapmanın bir yolu var mı?
PikkuKatja

28
Bu faktörler için işe yaramaz, df[df=="xyz"]<-"abc""geçersiz faktör seviyesi" hatası verir. Daha genel bir çözüm var mı?
glallen 02

1
benim için çalışmıyor. Bunu denedim: dfSmallDiscreteCustomSalary [dfSmallDiscreteCustomSalary $ salary == "<= 50K"] <- "49K". Yine benzersiz (dfSmallDiscreteCustomSalary $ maaş) için şunu alıyorum: [1]> 50K <= 50K
Codious-JR

3
glallen ... bir faktör sütununu zaten bir faktör olan yeni bir değerle değiştirmeye çalışıyorsanız, önermek üzere olduğum şeyin muhtemelen daha akıllıca yolları vardır, ancak df $ factorcolumn <- as.character ( df $ factorcolumn), sonra değişikliğinizi yapın ve tekrar faktöre çevirerek bitirin ... df $ faktörkolumn <- as.factor (df $ faktörkolumn); yeni seviyeniz ve istediğiniz değer ile tamamlanacaktır.
Joshua Eric Turcotte

Bulunan: df.na.replace (df.columns, Harita ("" -> "NA")). Göster. İlginç bir şekilde, değer olarak null ile değiştiremiyorum. Alıyorum: java.lang.IllegalArgumentException: Desteklenmeyen değer türü java.lang.String (null). org.apache.spark.sql.DataFrameNaFunctions.org $ apache $ spark $ sql $ DataFrameNaFunctions $$ convertToDouble (DataFrameNaFunctions.scala: 434)
sriram

35

PikkuKatja ve glallen daha genel bir çözüm istediği ve henüz yorum yapamadığım için bir cevap yazacağım. İfadeleri aşağıdaki gibi birleştirebilirsiniz:

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

Faktörler için, zxzak'ın kodu zaten faktörleri verir:

> 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

Başınız derde girerse, faktörleri geçici olarak bırakmanızı öneririm.

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

20

İşte birkaç dplyrseçenek:

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

Tüm veri kümesindeki birkaç dizeyi NA'larla değiştirmek için tüm sütunlar çözümünü kullanmaya nasıl devam edersiniz?
Tea Tree

4

Data.table'ı hızlı bir şekilde elde etmek için kullanabiliriz. Önce faktörsüz df oluşturun,

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

Şimdi kullanabilirsin

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

ve bunu bir data.frame'e geri dönüştürebilirsiniz.

setDF(df)

Yalnızca data.frame'i kullanmak istiyorsanız ve faktörleri daha zor tutmak istiyorsanız,

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

değer her sütunun adıdır. Bir döngüye eklemeniz gerekir.


2
Bu kullanım örneği için neden harici bir kitaplık kullanasınız? Bu tek satırla çözülebilirse neden bir döngü? Cevabınız, halihazırda mevcut olan cevapların ötesine nasıl değer katıyor? Sert olmak niyetinde değilim, sanırım bir şeyi kaçırıyorum, dolayısıyla sorular.
sedot

2
Büyük veri kümeleri için çok daha hızlı. Kullanıcının kendisi için en iyisini seçebilmesi için bir alternatif ekler.
Skan

0

Bir veri çerçevesindeki birden çok değeri değiştirmek istiyorsanız, tüm sütunlar arasında döngü yapmak yardımcı olabilir.

Değiştirmek istediğinizi söyleyin ""ve 100:

na_codes <- c(100, "")
for (i in seq_along(df)) {
    df[[i]][df[[i]] %in% na_codes] <- NA
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.