Как мне заполнить значения для столбцов на основе сопоставления нескольких значений строк других столбцов в R - PullRequest
0 голосов
/ 07 октября 2018

Данные выглядят так, как показано ниже.

 time <- c('Nov 1st 2014, 17:36:50.000','Nov 1st 2014, 17:36:50.000',
          'Nov 1st 2014, 17:36:50.000','Nov 1st 2014, 17:36:50.000', 'Nov 1st 2014, 17:37:50.000','Nov 1st 2014, 17:37:50.000','Nov 1st 2014, 17:37:50.000')
A <- c('20.79','NA','NA','NA','21.8','NA','NA')  
B <- c('NA','97.017','94.321','85.014','NA','87.1','67.1')
C <- c('NA','C1','C2','C3','NA','C1','C2')
D <- c('L1','L1','L1','L1','L2','L2','L2')
C1 <- c('NA','NA','NA','NA','NA','NA','NA')
C2 <- c('NA','NA','NA','NA','NA','NA','NA')
C3 <- c('NA','NA','NA','NA','NA','NA','NA')
df <- data.frame(time,A,B,C,D,C1,C2,C3)

Мне нужен вывод в следующем формате.

#   time                           A     B  C    D        C1     C2      C3
# 1 Nov 1st 2014, 17:36:50.000  20.79    NA NA   L1       97.02  94.321  85.014
    Nov 1st 2014, 17:37:50.000  21.8     NA NA   L2       87.1   67.1   47.3

Как получить данные в указанном формате в виде одной строки в виде столбцов"time" и "D" одинаковы для всех строк?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Пошаговый подход

Если я правильно понимаю, набор данных OP фактически состоит из двух смешанных наборов данных:

df
                        time     A      B  C  D C1 C2 C3
1 Nov 1st 2014, 17:36:50.000 20.79     NA NA L1 NA NA NA
2 Nov 1st 2014, 17:36:50.000    NA 97.017 C1 L1 NA NA NA
3 Nov 1st 2014, 17:36:50.000    NA 94.321 C2 L1 NA NA NA
4 Nov 1st 2014, 17:36:50.000    NA 85.014 C3 L1 NA NA NA
5 Nov 1st 2014, 17:37:50.000  21.8     NA NA L2 NA NA NA
6 Nov 1st 2014, 17:37:50.000    NA   87.1 C1 L2 NA NA NA
7 Nov 1st 2014, 17:37:50.000    NA   67.1 C2 L2 NA NA NA

, которые необходиморазделить:

library(data.table)
df1 <- setDT(df)[A != "NA", .(time, A, D)]
df1
                         time     A  D
1: Nov 1st 2014, 17:36:50.000 20.79 L1
2: Nov 1st 2014, 17:37:50.000  21.8 L2

и

df2 <- df[A == "NA", .(time, B, C, D)]
df2
                         time      B  C  D
1: Nov 1st 2014, 17:36:50.000 97.017 C1 L1
2: Nov 1st 2014, 17:36:50.000 94.321 C2 L1
3: Nov 1st 2014, 17:36:50.000 85.014 C3 L1
4: Nov 1st 2014, 17:37:50.000   87.1 C1 L2
5: Nov 1st 2014, 17:37:50.000   67.1 C2 L2

Ключевые столбцы, которые идентифицируют уникальные подмножества строк:time и D.Столбцы C1, C2 и C3 удаляются, так как они будут созданы на следующем шаге.

Второй набор данных должен быть преобразован из длинного в широкий формат:

wide <- dcast(df2, time + D ~ C, value.var = "B")
wide
                         time  D     C1     C2     C3
1: Nov 1st 2014, 17:36:50.000 L1 97.017 94.321 85.014
2: Nov 1st 2014, 17:37:50.000 L2   87.1   67.1   <NA>

Теперь оба частичных результата можно объединить:

df1[wide, on = .(time, D)]
                         time     A  D     C1     C2     C3
1: Nov 1st 2014, 17:36:50.000 20.79 L1 97.017 94.321 85.014
2: Nov 1st 2014, 17:37:50.000  21.8 L2   87.1   67.1   <NA>

Обратите внимание, что столбцы B и C имеютбыло исключено из результата, поскольку они не передают информацию.

Компактный код

Эти шаги можно объединить в меньшее количество операторов:

library(data.table)
setDT(df)[, (paste0("C", 1:3)) := NULL]
df[A != "NA"][dcast(df[C != "NA"], time + D ~ C, value.var = "B"), on = .(time, D)]
                         time     A  B  C  D     C1     C2     C3
1: Nov 1st 2014, 17:36:50.000 20.79 NA NA L1 97.017 94.321 85.014
2: Nov 1st 2014, 17:37:50.000  21.8 NA NA L2   87.1   67.1   <NA>

Данные

, предоставленные OP, со значениями NA, заданными в виде строк

time <- c('Nov 1st 2014, 17:36:50.000','Nov 1st 2014, 17:36:50.000',
          'Nov 1st 2014, 17:36:50.000','Nov 1st 2014, 17:36:50.000', 'Nov 1st 2014, 17:37:50.000','Nov 1st 2014, 17:37:50.000','Nov 1st 2014, 17:37:50.000')
A <- c('20.79','NA','NA','NA','21.8','NA','NA')  
B <- c('NA','97.017','94.321','85.014','NA','87.1','67.1')
C <- c('NA','C1','C2','C3','NA','C1','C2')
D <- c('L1','L1','L1','L1','L2','L2','L2')
C1 <- c('NA','NA','NA','NA','NA','NA','NA')
C2 <- c('NA','NA','NA','NA','NA','NA','NA')
C3 <- c('NA','NA','NA','NA','NA','NA','NA')
df <- data.frame(time,A,B,C,D,C1,C2,C3)
0 голосов
/ 08 октября 2018

Вы можете сделать это с помощью dplyr::gather(), чтобы преобразовать B в C1, C2, C3, а затем dplyr::join() в другие столбцы, предполагая уникальную дату / время.

library(dplyr)
library(tidyr)

df %>%
  select(time, A, B, C, D) %>%
  filter(!is.na(A)) %>%
  left_join(
    df %>%
      select(time, C, B, D) %>%
      spread(C, B) %>%
      select(-`<NA>`),
    by = c("time", "D")
  )

#                         time     A  B    C  D     C1     C2     C3
# 1 Nov 1st 2014, 17:36:50.000 20.79 NA <NA> L1 97.017 94.321 85.014
# 2 Nov 1st 2014, 17:37:50.000 21.80 NA <NA> L2 87.100 67.100 47.300

данные

df <- read.table(text = "time A B C D C1 C2 C3
1 'Nov 1st 2014, 17:36:50.000' 20.79 NA NA L1 NA NA NA
2 'Nov 1st 2014, 17:36:50.000' NA 97.017 C1 L1 NA NA NA
3 'Nov 1st 2014, 17:36:50.000' NA 94.321 C2 L1 NA NA NA
4 'Nov 1st 2014, 17:36:50.000' NA 85.014 C3 L1 NA NA NA
5 'Nov 1st 2014, 17:37:50.000' 21.8 NA NA L2 NA NA NA
6 'Nov 1st 2014, 17:37:50.000' NA 87.1 C1 L2 NA NA NA
7 'Nov 1st 2014, 17:37:50.000' NA 67.1 C2 L2 NA NA NA
8 'Nov 1st 2014, 17:37:50.000' NA 47.3 C3 L2 NA NA NA",
                 header = T,
                 stringsAsFactors = F)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...