Замінити всі конкретні значення у фреймі даних


91

Маючи фрейм даних, як мені зробити заміну всіх певних значень уздовж усіх рядків і стовпців. Скажімо, наприклад, я хочу замінити всі порожні записи на NA'(без введення позицій):

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

Відповіді:


139

Подобається це:

> 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); він буде укомплектований вашим новим рівнем та бажаним значенням.
Джошуа Ерік Туркотт

Знайшов: df.na.replace (df.columns, Map ("" -> "NA")). Show. Цікаво, що я не можу замінити null як значення. Я отримую: java.lang.IllegalArgumentException: Непідтримуваний тип значення java.lang.String (null). на org.apache.spark.sql.DataFrameNaFunctions.org $ apache $ spark $ sql $ DataFrameNaFunctions $$ convertToDouble (DataFrameNaFunctions.scala: 434)
sriram

34

Оскільки 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)

18

Ось кілька 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'))

Як би ви використали рішення всіх стовпців для заміни декількох рядків на NA у цілому наборі даних?
Чайне дерево

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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.