【问题标题】:R_splitting a data frame based on column-wise NA value occuranceR根据列式NA值的出现拆分数据帧
【发布时间】:2021-05-14 07:30:18
【问题描述】:

样本数据

set.seed(16)
aaa <- 1:1000
aaa[round(runif(100,1,1000))] <- NA
aaa.df <- as.data.frame(matrix(aaa, ncol=5))

我希望 aaa.df 根据包含 NA 值的列分为多个组,例如,如果第 10、16、200 行在同一列中具有 NA 值,我想要这些行在一组中,依此类推。它也应该在 a 时工作。连续没有 NA 值和 b。一行中有多个 NA 值。

分组时我也想保留原来的行号。

编辑:为了更清楚,这是预期的输出(使用 Taufi 的答案获得,但我仍在寻找更优雅的方式)

[[1]]
# A tibble: 119 x 6
    V1.y  V2.y  V3.y  V4.y  V5.y    V6
   <int> <int> <int> <int> <int> <int>
 1     1   201   401   601   801     1
 2     2   202   402   602   802     2
 3     3   203   403   603   803     3
 4     4   204   404   604   804     4
 5     5   205   405   605   805     5
 6     6   206   406   606   806     6
 7     7   207   407   607   807     7
 8     8   208   408   608   808     8
 9     9   209   409   609   809     9
10    10   210   410   610   810    10
# ... with 109 more rows

[[2]]
# A tibble: 14 x 6
    V1.y  V2.y  V3.y  V4.y  V5.y    V6
   <int> <int> <int> <int> <int> <int>
 1    20   220   420   620    NA    20
 2    32   232   432   632    NA    32
 3    47   247   447   647    NA    47
 4    70   270   470   670    NA    70
 5    85   285   485   685    NA    85
 6    92   292   492   692    NA    92
 7   129   329   529   729    NA   129
 8   132   332   532   732    NA   132
 9   137   337   537   737    NA   137
10   151   351   551   751    NA   151
11   152   352   552   752    NA   152
12   168   368   568   768    NA   168
13   178   378   578   778    NA   178
14   181   381   581   781    NA   181

[[3]]
# A tibble: 15 x 6
    V1.y  V2.y  V3.y  V4.y  V5.y    V6
   <int> <int> <int> <int> <int> <int>
 1    11   211   411    NA   811    11
 2    37   237   437    NA   837    37
 3    62   262   462    NA   862    62
 4    82   282   482    NA   882    82
 5    83   283   483    NA   883    83
 6    89   289   489    NA   889    89
 7   107   307   507    NA   907   107
 8   115   315   515    NA   915   115
 9   116   316   516    NA   916   116
10   117   317   517    NA   917   117
11   118   318   518    NA   918   118
12   165   365   565    NA   965   165
13   176   376   576    NA   976   176
14   189   389   589    NA   989   189
15   200   400   600    NA  1000   200

[[4]]
# A tibble: 1 x 6
   V1.y  V2.y  V3.y  V4.y  V5.y    V6
  <int> <int> <int> <int> <int> <int>
1    12   212   412    NA    NA    12

[[5]]
# A tibble: 16 x 6
    V1.y  V2.y  V3.y  V4.y  V5.y    V6
   <int> <int> <int> <int> <int> <int>
 1    17   217    NA   617   817    17
 2    28   228    NA   628   828    28
 3    31   231    NA   631   831    31
 4    48   248    NA   648   848    48
 5    58   258    NA   658   858    58
 6    72   272    NA   672   872    72
 7    80   280    NA   680   880    80
 8   126   326    NA   726   926   126
 9   144   344    NA   744   944   144
10   145   345    NA   745   945   145
11   149   349    NA   749   949   149
12   153   353    NA   753   953   153
13   186   386    NA   786   986   186
14   190   390    NA   790   990   190
15   192   392    NA   792   992   192
16   196   396    NA   796   996   196
and so on..

【问题讨论】:

    标签: r dataframe split grouping


    【解决方案1】:

    一个快速但不是很优雅的解决方案如下。注意后面的原始行号在V6中。

    aaa.df %<>% mutate(Rownum = 1:nrow(aaa.df))
    Aux.df <- cbind(is.na(aaa.df[, 1:(ncol(aaa.df) - 1)]), 1:nrow(aaa.df)) %>% 
                        as.data.frame %>% 
                                group_by(V1, V2, V3, V4, V5) %>%  
                                              group_split
    Sol <- lapply(Aux.df, function(x) inner_join(x, aaa.df, by = c("V6"="Rownum")) %>%
                                     select(V1.y, V2.y, V3.y, V4.y, V5.y, V6)) 
    

    输出

        > Sol
    [[1]]
    # A tibble: 119 x 6
        V1.y  V2.y  V3.y  V4.y  V5.y    V6
       <int> <int> <int> <int> <int> <int>
     1     1   201   401   601   801     1
     2     2   202   402   602   802     2
     3     3   203   403   603   803     3
     4     4   204   404   604   804     4
     5     5   205   405   605   805     5
     6     6   206   406   606   806     6
     7     7   207   407   607   807     7
     8     8   208   408   608   808     8
     9     9   209   409   609   809     9
    10    10   210   410   610   810    10
    # ... with 109 more rows
    
    [[2]]
    # A tibble: 14 x 6
        V1.y  V2.y  V3.y  V4.y  V5.y    V6
       <int> <int> <int> <int> <int> <int>
     1    20   220   420   620    NA    20
     2    32   232   432   632    NA    32
     3    47   247   447   647    NA    47
     4    70   270   470   670    NA    70
     5    85   285   485   685    NA    85
     6    92   292   492   692    NA    92
     7   129   329   529   729    NA   129
     8   132   332   532   732    NA   132
     9   137   337   537   737    NA   137
    10   151   351   551   751    NA   151
    11   152   352   552   752    NA   152
    12   168   368   568   768    NA   168
    13   178   378   578   778    NA   178
    14   181   381   581   781    NA   181
    ....
    

    等等……

    【讨论】:

    • 谢谢@Taufi。有用。在接受最优雅的解决方案之前,我将等待更多答案。
    【解决方案2】:

    除了我之前更暴力的答案之外,我还提出了以下更优雅的单行方式,避免了任何不必要的连接或中间分配步骤。既然您已经接受了我之前的回答,我就让它保持现状,并在下面添加概念上不同的单行。这个想法是基于which() 中的pasted 列号split() data.frame,表明NA 的存在。

    split(aaa.df, 
               apply(aaa.df, 1, 
                                function(x) paste(which(is.na(x)), collapse = ",")))
    

    输出

    $`1`
        V1  V2  V3  V4  V5
    77  NA 277 477 677 877
    93  NA 293 493 693 893
    97  NA 297 497 697 897
    109 NA 309 509 709 909
    119 NA 319 519 719 919
    140 NA 340 540 740 940
    154 NA 354 554 754 954
    158 NA 358 558 758 958
    171 NA 371 571 771 971
    172 NA 372 572 772 972
    
    $`1,2,3`
       V1 V2 V3  V4  V5
    51 NA NA NA 651 851
    
    $`1,3,5`
       V1  V2 V3  V4 V5
    75 NA 275 NA 675 NA
    
    $`1,4`
        V1  V2  V3 V4  V5
    194 NA 394 594 NA 994
    
    $`1,4,5`
       V1  V2  V3 V4 V5
    49 NA 249 449 NA NA
     ... 
    

    等等……

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 2023-03-31
      • 2021-09-18
      相关资源
      最近更新 更多