Разверните фрейм данных на основе столбцов в фрейме данных в R - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть следующий кадр данных в R

 df<-data.frame( 
       "Val1"=seq(from=1, to=40, by=5), 'Val2'=c(2,4,2,5,11,3,5,3), 
       "Val3"=seq(from=5, to=40, by=5), "Val4"=c(3,5,7,3,7,5,7,8))

Результирующий кадр данных выглядит следующим образом.Val 1, Val3 являются причинными переменными, а Val2, Val4 являются зависимыми переменными

       Val1 Val2 Val3 Val4      
 1        1    2    5     3  
 2        6    4   10     5  
 3        11    2   15    7  
 4        16    5   20    3  
 5        21   11   25    7  
 6        26    3   30    5  
 7        31    5   35    7  
 8        36    3   40    8  

Я хочу получить следующий фрейм данных в качестве вывода

      Val1   Val2  Val3  Val4
  1     1      2     1    NA
  2     2      NA    2    NA
  3     3      NA    3    3
  4     4      NA    4   NA
  5     5      NA    5   NA
  6     6      4     6   NA
  7     7      NA    7   NA
  8     8      NA    8   NA
  9     9      NA    9   NA
  10   10      NA   10   5
  11   11      2    11   NA
  12   12      NA   12   NA
  13   13      NA   13   NA
  14   14      NA   14   NA
  15   15      NA   15   7
  16   16      5    16   NA
  17   17      NA   17   NA
  18   18      NA   18   NA
  19   19      NA   19   NA
  20   20       NA   20   3
  21   21       11   21   NA
 22   22       NA   22   NA
 23   23       NA   23   NA
 24   24       NA   24   NA
 25   25       NA   25   7
 26   26        3    26   NA
 27   27       NA   27   NA
 28   28       NA   28   NA
 29   29       NA   29   NA
 30   30       NA   30   5
 31   31       5    31   NA
 32   32       NA   32   NA
 33   33       NA   33   NA
 34   34       NA   34   NA
 35   35        NA   35   7
 36   36        3    36   NA
 37   37        NA   37   NA
 38   38        NA   38   NA
 39   39        NA   39   NA
 40   40        NA   40   8

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

   df2<-data.frame('Val1'=

   seq(from=min(na.omit(c(df$Val1, df$Val3))), to= max(na.omit(c(df$Val1, 
   df$Val3))), by=1), "Val3"=seq(from=min(na.omit(c(df$Val1, df$Val3))), to= 
   max(na.omit(c(df$Val1, df$Val3))), by=1))
     ###### Create two loops 
     for(i in df$Val1){
    for(j in df2$Val1){
    if(i==j){
    df2$Val2[df2$Val1==j]=df$Val2[df$Val1==i]
    } else{df2$Val2[df2$Val1==j]=NA}}}


   for(i in df$Val3){  for(j in df2$Val3){
   if(i==j){df2$Val4[df2$Val3==j]=df$Val4[df$Val3==i]
  } else{df2$Val4[df2$Val3==j]=NA}}}

Есть ли более быстрый векторизованный способ сделать то же самое.просить кого-нибудь помочь

1 Ответ

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

Если в вашем выходном примере есть небольшая ошибка (строка 3 должна показывать NA для Val4, а 3 в строке 3 должна быть в строке 5), это работает:

library(tidyverse)

df_new <- bind_cols(
  df %>%
    select(Val1, Val2) %>%
    complete(., expand(., Val1 = 1:40)),
  df %>%
    select(Val3, Val4) %>%
    complete(., expand(., Val3 = 1:40))
)

> df_new
# A tibble: 40 x 4
    Val1  Val2  Val3  Val4
   <dbl> <dbl> <dbl> <dbl>
 1     1     2     1    NA
 2     2    NA     2    NA
 3     3    NA     3    NA
 4     4    NA     4    NA
 5     5    NA     5     3
 6     6     4     6    NA
 7     7    NA     7    NA
 8     8    NA     8    NA
 9     9    NA     9    NA
10    10    NA    10     5
# ... with 30 more rows

Мы используем bind_cols(), чтобы соединить две части кадра данных: сначала мы выбираем первые два столбца, expand() причинную переменную и complete() данные, затем мы делаем это снова для третьего и четвертого столбца.

...