Замена NA в столбце с заранее заданными значениями на основе значения в другом столбце - PullRequest
0 голосов
/ 06 января 2019

У меня очень простой вопрос. Однако все, что я могу найти, - это очень сложные ответы, которые не выполняют именно то, что мне нужно.

Что было ближе всего, я нашел здесь:

Ответ от flodel и eddi (data.table)

Однако я хотел бы дополнительно указать, как обрабатывать NA в указанном столбце на основе значения в другом столбце.

У меня есть data.table, в котором есть столбцы с NA, где fac - фактор-переменная.

df <- fread(
  "A   B   C   fac   H   I   J   iso   year   matchcode
     0   1   1   NA   0   1   0   NLD   2009   NLD2009
     1   0   0   NA   1   0   1   NLD   2014   NLD2014
     0   0   0   B   1   0   0   AUS   2011   AUS2011
     1   0   1   B   0   1   0   AUS   2007   AUS2007
     0   1   0   NA  0   1   1   USA   2007   USA2007
     0   0   1   NA  0   0   1   USA   2011   USA2010
     0   1   0   NA  0   0   0   USA   2013   USA2013
     1   0   1   A   0   1   0   BLG   2007   BLG2007
     0   1   0   A   1   0   1   BEL   2009   BEL2009
     1   0   1   A   0   1   0   BEL   2012   BEL2012",
  header = TRUE
)

Я хотел бы назначить значения D и E для NA в столбце fac на основе значений в iso3c. Поэтому, когда iso3c == NLD, NA в fac следует заменить на D, а когда iso3c == USA NA в fac следует заменить на E, что приводит к следующему результату.

df <- fread(
  "A   B   C   fac   H   I   J   iso   year   matchcode
     0   1   1   D   0   1   0   NLD   2009   NLD2009
     1   0   0   D   1   0   1   NLD   2014   NLD2014
     0   0   0   B   1   0   0   AUS   2011   AUS2011
     1   0   1   B   0   1   0   AUS   2007   AUS2007
     0   1   0   E  0   1   1   USA   2007   USA2007
     0   0   1   E  0   0   1   USA   2011   USA2010
     0   1   0   E  0   0   0   USA   2013   USA2013
     1   0   1   A   0   1   0   BLG   2007   BLG2007
     0   1   0   A   1   0   1   BEL   2009   BEL2009
     1   0   1   A   0   1   0   BEL   2012   BEL2012",
  header = TRUE
)

РЕДАКТИРОВАТЬ: Факт, что fac является фактор-переменной, дал некоторые проблемы. То, что сработало, это:

df$fac<- as.character(df$fac)
df[, fac:= ifelse(is.na(fac) & iso3c == "NLD", "D", 
                   ifelse(is.na(fac) & iso3c == "USA", "E", wbgroup))][]
df[, fac:= factor(fac, levels = c(levels(fac), c('A', 'B', 'C', 'D', 'E', 'F', 'G')))]

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Другой вариант, использующий data.table с двумя ifelse операторами.

library(data.table)

df[, fac := ifelse(is.na(fac) & iso == "NLD", "D", 
                   ifelse(is.na(fac) & iso == "USA", "E", fac))][]
#     A B C fac H I J iso year matchcode
#  1: 0 1 1   D 0 1 0 NLD 2009   NLD2009
#  2: 1 0 0   D 1 0 1 NLD 2014   NLD2014
#  3: 0 0 0   B 1 0 0 AUS 2011   AUS2011
#  4: 1 0 1   B 0 1 0 AUS 2007   AUS2007
#  5: 0 1 0   E 0 1 1 USA 2007   USA2007
#  6: 0 0 1   E 0 0 1 USA 2011   USA2010
#  7: 0 1 0   E 0 0 0 USA 2013   USA2013
#  8: 1 0 1   A 0 1 0 BLG 2007   BLG2007
#  9: 0 1 0   A 1 0 1 BEL 2009   BEL2009
# 10: 1 0 1   A 0 1 0 BEL 2012   BEL2012
0 голосов
/ 06 января 2019

Нам нужно указать логическое условие в i и выполнить присвоение. Поскольку для изменения значения есть только два случая, это можно сделать в два этапа

df[is.na(fac) & iso == 'NLD', fac := 'D'
  ][is.na(fac) & iso == 'USA', fac := 'E'][]
#    A B C fac H I J iso year matchcode
# 1: 0 1 1   D 0 1 0 NLD 2009   NLD2009
# 2: 1 0 0   D 1 0 1 NLD 2014   NLD2014
# 3: 0 0 0   B 1 0 0 AUS 2011   AUS2011
# 4: 1 0 1   B 0 1 0 AUS 2007   AUS2007
# 5: 0 1 0   E 0 1 1 USA 2007   USA2007
# 6: 0 0 1   E 0 0 1 USA 2011   USA2010
# 7: 0 1 0   E 0 0 0 USA 2013   USA2013
# 8: 1 0 1   A 0 1 0 BLG 2007   BLG2007
# 9: 0 1 0   A 1 0 1 BEL 2009   BEL2009
#10: 1 0 1   A 0 1 0 BEL 2012   BEL2012

Если необходимо заменить много значений, выполните объединение с набором данных ключ / значение и выполните присвоение

df[data.table(fac = NA_character_, iso = c('NLD', 'USA'), 
        val = c('D', 'E')), fac := val, on = .(fac, iso)]

ПРИМЕЧАНИЕ. Столбцы fac, iso относятся к классу character. Если fac является классом factor и 'D', 'E' levels не существует в столбце, то создайте новый levels перед выполнением присваивания, т.е.

df[, fac := factor(fac, levels = c(levels(fac), c('D', 'E')))]
...