【问题标题】:Expand a dataframe based on columns in the dataframe in R根据 R 中数据框中的列展开数据框
【发布时间】:2019-06-30 01:28:16
【问题描述】:

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

是否有更快的矢量化方式来完成相同的任务。求人帮忙

【问题讨论】:

    标签: r performance dataframe for-loop if-statement


    【解决方案1】:

    假设您的输出示例中有一个小错误(第 3 行应该显示 Val4NA,第 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() 数据,然后我们对第三和第四列再次执行此操作。

    【讨论】:

    • 谢谢。这正是我所需要的。循环减慢了代码的速度。怎么知道我们使用的是 tidytext 还是 plyr 包?我可以将代码扩展到更多列吗
    • 相关包为dplyr。您是指一个因果变量和一个因变量的更多组合,还是每个因果变量有多个因变量?
    • 一因一因变量的更多组合
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多