Разверните «NA» для заполнения нескольких строк с помощью группирующей переменной - PullRequest
3 голосов
/ 29 октября 2019

У меня есть фрейм данных, где у каждого SerialNo есть строка пропущенных значений, а у некоторых могут быть заполненные данные. Мне нужно расширить строки NA до двух новых строк, состоящих из уникальных значений PartsUsed.

Я считаю, что я на правильном пути, используя dplyr complete или expand но я не могу получить правильные аргументы.

Ниже приведены примеры наборов данных (тот, который у меня сейчас есть, и тот, который является целевым df)

begin_ex_df <- tibble(
  SerialNo = c(1234, 5678, 5678, 5678, 9012, 1357, 1357, 1357, 2468, 8080),
  PartsUsed = c(NA, "A", "B", NA, NA, "A", "B", NA, NA, NA),
  Values = c(NA, 10, 15, NA, NA, 11, 14, NA, NA, NA)
)

ending_ex_df <- tibble(
  SerialNo = c(1234, 1234, 5678, 5678, 5678, 5678, 9012, 9012, 1357, 1357, 1357, 1357, 2468, 2468, 8080, 8080),
  PartsUsed = c("A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B"),
  Values = c(0, 0, 10, 15, 0, 0, 0, 0, 11, 14, 0, 0, 0, 0, 0, 0)
)

Я ожидаю каждый *Строка 1014 * должна быть расширена, чтобы иметь "A" и "B" в PartsUsed, и она Values заполняется до 0 (обратите внимание, что заполнение значения не является необходимым - оно может остаться NA.) Строки, которыеуже "A" или "B" следует оставить в покое.

Ответы [ 2 ]

3 голосов
/ 29 октября 2019

Вот альтернатива, которая будет содержать дубликаты SerialNo

x <- subset(begin_ex_df, is.na(begin_ex_df$PartsUsed)) 
x <- expand.grid(SerialNo = x$SerialNo, PartsUsed = c("A", "B"))
x$Values <- 0 
y <- subset(begin_ex_df, !is.na(begin_ex_df$PartsUsed))

new_df <- rbind(x, y)

new_df[order(new_df$SerialNo),]

#  SerialNo PartsUsed Values
#1      1234         A      0
#2      1234         B      0
#3      1357         A      0
#4      1357         B      0
#5      1357         A     11
#6      1357         B     14
#7      2468         A      0
#8      2468         B      0
#9      5678         A      0
#10     5678         B      0
#11     5678         A     10
#12     5678         B     15
#13     8080         A      0
#14     8080         B      0
#15     9012         A      0
#16     9012         B      0

Редактировать

Если вы хотите использовать tidyr complete, тогда вы можете group_by создать индекс длягруппы с NA и без, а затем в конце NA (вы также можете удалить столбец Ind).

library(dplyr)
library(tidyr)

begin_ex_df %>% 
   group_by(SerialNo, Ind = if_else(is.na(PartsUsed), "no", "yes")) %>% 
   complete(., SerialNo, PartsUsed = c("A", "B"), fill = list(Values = 0)) %>% 
   na.omit()

#  Ind   SerialNo PartsUsed Values
#   <chr>    <dbl> <chr>      <dbl>
# 1 no        1234 A              0
# 2 no        1234 B              0
# 3 no        1357 A              0
# 4 no        1357 B              0
# 5 yes       1357 A             11
# 6 yes       1357 B             14
# 7 no        2468 A              0
# 8 no        2468 B              0
# 9 no        5678 A              0
#10 no        5678 B              0
#11 yes       5678 A             10
#12 yes       5678 B             15
#13 no        8080 A              0
#14 no        8080 B              0
#15 no        9012 A              0
#16 no        9012 B              0

2 голосов
/ 29 октября 2019

complete от tidyr, а не dplyr, но это, безусловно, хорошее направление. Его нужно объединить с filter из dplyr, чтобы удалить созданные линии NA.

tidyr::complete(df,SerialNo,PartsUsed,fill=list(Values=0)) %>% 
  dplyr::filter(!is.na(PartsUsed))

# A tibble: 12 x 3
   SerialNo PartsUsed Values
      <dbl> <chr>      <dbl>
 1     1234 A              0
 2     1234 B              0
 3     1357 A             11
 4     1357 B             14
 5     2468 A              0
 6     2468 B              0
 7     5678 A             10
 8     5678 B             15
 9     8080 A              0
10     8080 B              0
11     9012 A              0
12     9012 B              0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...