扩大基于列的数据帧在R中的数据帧

问题描述 投票:1回答:1

我在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))

所得到的数据帧如下所示。瓦尔1,VAL3是因果变量和值2,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}}}

有没有达到同样的更快的向量化的方式。请求一些人帮忙

r performance dataframe for-loop if-statement
1个回答
1
投票

假设有一个在你的输出例如略有误差(第3行应显示为NAVal4 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()数据,然后我们在第三和第四列做一遍。

© www.soinside.com 2019 - 2024. All rights reserved.