Заполнение NA и исправление данных на основе последовательности в последовательности - PullRequest
0 голосов
/ 30 октября 2019

У меня есть фрейм данных с двумя проблемами, которые я пытаюсь исправить. Вот игрушечный пример.

        require(data.table)
        tempdt <- data.table(ID1=rep(1:6,each=2),ID2=rep(letters[1:2],6),name=c('john','john',NA,'mike','steve',NA,'bob',NA,NA,'henry','joe','frank'))

            ID1 ID2  name
         1:   1   a  john
         2:   1   b  john
         3:   2   a  <NA>
         4:   2   b  mike
         5:   3   a steve
         6:   3   b  <NA>
         7:   4   a   bob
         8:   4   b  <NA>
         9:   5   a  <NA>
        10:   5   b henry
        11:   6   a   joe
        12:   6   b frank

Существует две последовательные группирующие переменные (ID1 в качестве основной последовательности и ID2 в качестве вторичной последовательности в ID1) и присвоение имени. Иногда имя отсутствует, и мне нужно заполнить его, основываясь на том, что назначено в этом ID1, и в других случаях у меня может быть 2 (или более) разных имени для одного и того же ID1, но должно быть только одно. Какое бы имя ни было первым в порядке ID2 в ID1, это должно быть назначенное имя для всего этого ID1

В конечном итоге поле имени должно выглядеть следующим образом: c('john','john','mike','mike','steve','steve','bob','bob','henry','henry','joe','joe')

Я мог бы подойти к этому, упорядочив данныефрейм (таблица), основанный на двух последовательных переменных, а затем выполняющий цикл for для ID1 и вносящий исправления, но, похоже, должен быть более чистый и эффективный способ последовательности вдоль ID1, сравнения последовательности ID2 в ID1 и внесения исправленийизбегая петли.

Есть мысли? У меня есть таблица данных, потому что я обычно работаю с ними, но в этом нет необходимости.

Будет

Ответы [ 2 ]

1 голос
/ 30 октября 2019

Это может работать:

tempdt %>% 
  group_by(ID1) %>% 
  arrange(ID1, ID2)
  mutate(name = first(na.omit(name)))

# A tibble: 12 x 3
# Groups:   ID1 [6]
     ID1 ID2   name 
   <int> <fct> <fct>
 1     1 a     john 
 2     1 b     john 
 3     2 a     mike 
 4     2 b     mike 
 5     3 a     steve
 6     3 b     steve
 7     4 a     bob  
 8     4 b     bob  
 9     5 a     henry
10     5 b     henry
11     6 a     joe  
12     6 b     joe
0 голосов
/ 30 октября 2019

Вы можете сделать следующее:

# Make a "Dictionary" of primary names per ID1 group
dict = tempdt[ , .(Name = first(name[!is.na(name)])), keyby = ID1] 

# Which ID1s correspond to NA names?
ID1_NA = tempdt[is.na(name), ID1]

# Draw correct names from the Dictionary
tempdt[is.na(name), name := dict[ID1_NA, Name]] 

Результат

> tempdt
    ID1 ID2  name
 1:   1   a  john
 2:   1   b  john
 3:   2   a  mike
 4:   2   b  mike
 5:   3   a steve
 6:   3   b steve
 7:   4   a   bob
 8:   4   b   bob
 9:   5   a henry
10:   5   b henry
11:   6   a   joe
12:   6   b frank

Я согласен с sindri_baldur, что существует некоторая путаница в отношении name[12]. Используя вашу логику, это должно быть joe, верно?

Хотите ли вы также учитывать не-NA name записи, которые нарушают вашу последовательность "имя в ID1 / 2"? Если это так, вы можете просто добавить tempdt[, name := first(name), keyby = ID1] в конец вышеуказанных операций, так как это заставит name[12] к joe.

...