【问题标题】:Split data frame by class regarding to OID按关于 OID 的类拆分数据帧
【发布时间】:2019-12-13 18:09:39
【问题描述】:

我尝试按类将数据帧拆分 50%。但是,我不想拆分具有相同 OID(对象标识符)的字段。我希望具有相同 OID 的字段位于同一集合中。

    #Data frame:
   "b1""b2""b3""CLASS"   "OID"
    110 134 119 "tree"      1
    112 133 118 "tree"      1
    105 125 110 "tree"      2
    112 132 117 "tree"      2
    109 125 115 "meadow"    6
    93  110 101 "meadow"    6
    86  106 95  "meadow"    7
    105 136 116 "meadow"    7
    102 128 111 "meadow"    8
    108 129 115 "meadow"    8
    113 134 119 "meadow"    8

预期数据:

#Expected:
    "b1""b2""b3""CLASS"   "OID"
    110 134 119 "tree"      1
    112 133 118 "tree"      1
    109 125 115 "meadow"    6
    93  110 101 "meadow"    6
    86  106 95  "meadow"    7
    105 136 116 "meadow"    7

【问题讨论】:

    标签: r dataframe split dplyr


    【解决方案1】:

    这将选择每个组中的上半部分行,以及与该上半部分中的行具有相同 OID 的任何行。

    library(dplyr)
    
    df %>% 
      group_by(CLASS) %>% 
      filter(OID %in% head(OID, n() %/% 2)) %>% 
      ungroup
    
    # # A tibble: 6 x 5
    #      b1    b2    b3 CLASS    OID
    #   <int> <int> <int> <chr>  <int>
    # 1   110   134   119 tree       1
    # 2   112   133   118 tree       1
    # 3   109   125   115 meadow     6
    # 4    93   110   101 meadow     6
    # 5    86   106    95 meadow     7
    # 6   105   136   116 meadow     7
    

    如果你的真实数据像这个例子一样按照 OID 排列,你也可以使用top_frac

    df %>% 
      group_by(CLASS) %>% 
      top_frac(.5, -OID)
    
    # # A tibble: 6 x 5
    #      b1    b2    b3 CLASS    OID
    #   <int> <int> <int> <chr>  <int>
    # 1   110   134   119 tree       1
    # 2   112   133   118 tree       1
    # 3   109   125   115 meadow     6
    # 4    93   110   101 meadow     6
    # 5    86   106    95 meadow     7
    # 6   105   136   116 meadow     7
    

    【讨论】:

      【解决方案2】:

      您的数据:

      df = structure(list(b1 = c(110L, 112L, 105L, 112L, 109L, 93L, 86L, 
      105L, 102L, 108L, 113L), b2 = c(134L, 133L, 125L, 132L, 125L, 
      110L, 106L, 136L, 128L, 129L, 134L), b3 = c(119L, 118L, 110L, 
      117L, 115L, 101L, 95L, 116L, 111L, 115L, 119L), CLASS = structure(c(2L, 
      2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("meadow", 
      "tree"), class = "factor"), OID = c(1L, 1L, 2L, 2L, 6L, 6L, 7L, 
      7L, 8L, 8L, 8L)), class = "data.frame", row.names = c(NA, -11L
      ))
      

      先创建一个函数,根据OID取1/2

      func = function(x){
      x[x$OID %in% x$OID[1:round(nrow(x)/2)],]
      }
      

      我们随机化 OID 的排序方式

      df$OID = factor(df$OID,levels=sample(unique(df$OID)))
      df = df[order(df$OID),]
      do.call(rbind,by(df,df$CLASS,func))
      

      这将确保您每次都随机获得 ~ 50%,并带有完整的 OID

      【讨论】:

      • 这个函数可以改成一分为二,得到两个数据帧(50:50)按照这个方法分割吗?
      • @Nicolas,你提供一个row ID,然后从原始data.frame中检索,那些没有包含在这个函数中的?
      猜你喜欢
      • 2021-11-06
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多