вставка номеров строк со значением NA с условием минимального требования к строке для каждого объекта в R - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть датафрейм, как показано ниже.Я хотел бы установить минимальную переменную строки (назовем ее min_row) для каждого ID, это означает, что в каждом ID должно быть не менее min_row записей.если его нет, я хочу вставить строку для этого ID со значением NA для другого столбца (здесь столбец subject).

min_row_id=3
df
ID    subject
1      A1
1      A2
2      A1
3      A1
3      A2
3      A3
3      A4

resutl:

ID   subject
1     A1
1     A2
1     NA
2     A1
2     NA
2     NA
3     A1
3     A2
3     A3
3     A4

Таким образом, у каждого ID есть как минимум 3 записи.
Как я могу сделать это в R?ТНХ

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Вот один из способов использования tidyr::complete.Мы создаем столбец record_number, который подсчитывает записи для каждой группы ID.Затем complete позволит нам заполнить все пропущенные строки, поэтому в каждой группе будет столько записей, сколько в группе было больше всего (или, если ни одна из групп не имеет 3 записей, они заполняются до 3 строк).Затем мы отфильтровываем посторонние строки больше 3 для каждой группы, которые были добавлены.

library(tidyverse)
tbl <- read_table2(
"ID    subject
1      A1
1      A2
2      A1
3      A1
3      A2
3      A3
3      A4" 
)

tbl %>%
  group_by(ID) %>%
  mutate(record_number = row_number()) %>%
  ungroup() %>%
  complete(ID, record_number = 1:max(3, max(record_number))) %>%
  filter(record_number <=3 | !is.na(subject))
#> # A tibble: 10 x 3
#>       ID record_number subject
#>    <dbl>         <int> <chr>  
#>  1     1             1 A1     
#>  2     1             2 A2     
#>  3     1             3 <NA>   
#>  4     2             1 A1     
#>  5     2             2 <NA>   
#>  6     2             3 <NA>   
#>  7     3             1 A1     
#>  8     3             2 A2     
#>  9     3             3 A3     
#> 10     3             4 A4

Создано в 2019-02-06 пакетом представлением (v0.2.1)

0 голосов
/ 07 февраля 2019

Другая base альтернатива.Используйте tapply для индексации ([) «субъекта» внутри каждого «ИД», от 1 до max группы length и 3 (min_row_id).Для индексов, которые превышают длину группы, соответствующее значение равно NA.

Воссоздайте 'ID' правильной длины путем rep, присваивая имя элементов списка длине каждого элемента (lengths),Используйте unlist для создания столбца «Тема».

l <- tapply(d$subject, d$ID, function(x) x[1:(max(c(length(x), 3)))])
data.frame(id = rep(names(l), lengths(l)), subject = unlist(l, use.names = FALSE))
#    id subject
# 1   1      A1
# 2   1      A2
# 3   1    <NA>
# 4   2      A1
# 5   2    <NA>
# 6   2    <NA>
# 7   3      A1
# 8   3      A2
# 9   3      A3
# 10  3      A4
0 голосов
/ 07 февраля 2019

Один из способов использования только базы R будет

#Get number of rows for each ID and subtract it from min_row_id
#keep only those which we need to add 
temp <- subset(aggregate(subject~ID, df, function(x) min_row_id - length(x)), 
               subject < min_row_id & subject > 0)

#Add those new rows and rbind the original dataframe
new_df <- rbind(df, do.call(rbind, mapply(function(x, y) 
                    data.frame(ID = x, subject = rep(NA, y)), 
                    temp$ID, temp$subject, SIMPLIFY = FALSE)))

#If needed order them according to ID
new_df[order(new_df$ID), ]

#   ID subject
#1   1      A1
#2   1      A2
#8   1    <NA>
#3   2      A1
#9   2    <NA>
#10  2    <NA>
#4   3      A1
#5   3      A2
#6   3      A3
#7   3      A4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...