как заменить NA на значение, которое позже будет введено с тем же идентификатором и датой - PullRequest
0 голосов
/ 10 июля 2020

У меня есть данные, которые выглядят, и я хочу заполнить n / a результатом, который позже вводится с тем же идентификатором и test_date, и вести только одну запись для каждого идентификатора каждый день. Что мне делать?

Вот коды для примеров данных:

ID <-c("1", "1", "1","2", "2")
Test_date <-c("2020-07-09", "2020-07-09","2020-07-09", "2020-07-07","2020-07-08")
Art <-c("N/A","D","N/A","N/A", "B")
PE<-c("N/A","N/A","B","A","N/A")

Sample.data <- data.frame(ID, Test_date, Art, PE)

Ответы [ 3 ]

1 голос
/ 10 июля 2020

В Base-R

Сначала измените символьные строки "N/A" на фактические NA

Sample.data[Sample.data=="N/A"] <- NA

теперь реальная суть ответа

merge(
    aggregate(Art ~ ID + Test_date, Sample.data, paste),
    aggregate(PE ~ ID + Test_date, Sample.data, paste),
    all=T
)

вывод:

  ID  Test_date  Art   PE
1  1 2020-07-09    D    B
2  2 2020-07-07 <NA>    A
3  2 2020-07-08    B <NA>
0 голосов
/ 10 июля 2020

Использование data.table:

library(data.table)

# Convert to data.table
setDT(Sample.data)
# Format NA properly as NA 
Sample.data[, c("Art", "PE") := lapply(.SD, function(x) fifelse(x == "N/A", NA_character_, x)), .SDcols = c("Art", "PE")]

Sample.data[, .(Art[!is.na(Art)], PE[!is.na(PE)]), by = .(ID, Test_date)]
#    ID  Test_date   V1   V2
# 1:  1 2020-07-09    D    B
# 2:  2 2020-07-07 <NA>    A
# 3:  2 2020-07-08    B <NA>

Альтернативно:

Sample.data[, lapply(.SD, function(x) x[!is.na(x)]), by = .(ID, Test_date)]
0 голосов
/ 10 июля 2020

( Отредактировано , чтобы исправить мою неправильную группировку.)

Я собираюсь предложить быстрое решение tidyverse, хотя это можно сделать (с немного большими усилиями) в базе R (и data.table).

Несколько задач:

  • заменить "N/A" (которая является полностью действительной и определенной строкой) на NA (на самом деле, NA_character_, поскольку в R существует более шести типов NA);
  • преобразовать Test_date в настоящий Date класс и отсортировать по нему;
  • заполнить по группам;
  • сгруппируйте по идентификатору / дате и оставьте только одну

Первые несколько сделаны с помощью

library(dplyr)
library(tidyr) # fill
Sample.data %>%
  mutate(Test_date = as.Date(Test_date)) %>%
  mutate_at(vars(Art, PE), ~ replace(., . == "N/A", NA_character_)) %>%
  arrange(Test_date) %>%
  group_by(ID, Test_date) %>%
  tidyr::fill(., Art, PE, .direction = "up") %>%
  ungroup()
# # A tibble: 5 x 4
#   ID    Test_date  Art   PE   
#   <chr> <date>     <chr> <chr>
# 1 2     2020-07-07 <NA>  A    
# 2 2     2020-07-08 B     <NA> 
# 3 1     2020-07-09 D     B    
# 4 1     2020-07-09 D     B    
# 5 1     2020-07-09 <NA>  B    

, хотя вам нужно подумать о том, что произойдет, когда ваш последнее наблюдение NA.

Теперь для вашей последней точки

и ведите только одну запись для каждого идентификатора каждый день

Я немного дополню сказанное выше. Я собираюсь вывести сначала , но, честно говоря, вы не предоставили достаточно информации, чтобы знать, должно ли оно быть first, last, sum, max, row-with-the-lessest- NA -values или что-то еще.

Sample.data %>%
  mutate(Test_date = as.Date(Test_date)) %>%
  mutate_at(vars(Art, PE), ~ replace(., . == "N/A", NA_character_)) %>%
  arrange(Test_date) %>%
  group_by(ID, Test_date) %>%
  tidyr::fill(., Art, PE, .direction = "up") %>%
  slice(1) %>%
  ungroup()
# # A tibble: 3 x 4
#   ID    Test_date  Art   PE   
#   <chr> <date>     <chr> <chr>
# 1 1     2020-07-09 D     B    
# 2 2     2020-07-07 <NA>  A    
# 3 2     2020-07-08 B     <NA> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...