【问题标题】:Split dataframe at specifi row and arrange columns into "sections" in R在特定行拆分数据框并将列排列到 R 中的“部分”中
【发布时间】:2021-04-24 05:41:34
【问题描述】:

我正在寻找一种解决方案,将数据帧拆分为具有指定长度的较小部分,然后将这些部分重新排列成一个新的数据帧。目标是在打印窄表时在单个页面上放置更多数据。例如:

index   v1
1   a
2   a
3   d
4   f
5   f
6   g
7   a
8   a
9   x
10  d
11  d
12  x
13  e
14  a
15  a
16  d
17  c
18  f
19  e
20  e
21  c

进入这个:

index   v1  index   v1
1   a   7   a
2   a   8   a
3   d   9   x
4   f   10  d
5   f   11  d
6   g   12  x
13  e   19  e
14  a   20  e
15  a   21  c
16  d       
17  c       
18  f       

在此示例中,我们在每 6 行之后拆分并排列成两列部分(如果我们的页面只能容纳 6 行)。将分割点和列部分计数作为变量会很好。又例如在Excel中输入了额外的数据后,如何逆向重新制作常规表格进行数据分析?

【问题讨论】:

    标签: r


    【解决方案1】:

    你可以这样做

    after <- 6
    cols <- 2
    f <- ((seq(nrow(df)) - 1) %/% after) %% cols
    d <- reshape(cbind(df, time = f, id = ave(f, f, FUN=seq)), dir="wide")
    
    d[-1]
    
       index.0 v1.0 index.1 v1.1
    1        1    a       7    a
    2        2    a       8    a
    3        3    d       9    x
    4        4    f      10    d
    5        5    f      11    d
    6        6    g      12    x
    13      13    e      19    e
    14      14    a      20    e
    15      15    a      21    c
    16      16    d      NA <NA>
    17      17    c      NA <NA>
    18      18    f      NA <NA>
    

    反向操作将是:

     reshape(d)[-(1:2)]
    

    【讨论】:

    • 按需工作。用重复的原始名称重命名很容易。你会这么好心并添加反向操作吗?将结果转换回原始结果。
    • @user2021713 已添加反向操作
    • reshape(d)[-(1:2)] 给我一个错误:match.arg(direction, c("wide", "long")) 中的错误:参数“direction”是缺失,没有默认值。仅仅添加 dir="long" 是不够的。
    • @user2021713 不更改 d。让 d 保持原样。您可能需要做的是将 d 分配给另一个变量,例如 e 然后在您 qant 时更改 e,只要您不更改 d
    • 那么来自 stats 包的 reshape() 函数有一个没有默认值的方向参数。所以得到这个错误是有道理的。我没有改变对象 d。
    【解决方案2】:

    不好看……

    cbindPad 函数(用于填充不完整的列)来自combining two data frames of different lengths

    library(tidyverse)
    
    cbindPad <- function(...){
      args <- list(...)
      n <- sapply(args,nrow)
      mx <- max(n)
      pad <- function(x, mx){
        if (nrow(x) < mx){
          nms <- colnames(x)
          padTemp <- matrix(NA, mx - nrow(x), ncol(x))
          colnames(padTemp) <- nms
          if (ncol(x)==0) {
            return(padTemp)
          } else {
            return(rbind(x,padTemp))
          }
        }
        else{
          return(x)
        }
      }
      rs <- lapply(args,pad,mx)
      return(do.call(cbind,rs))
    }
    
    
    df <- tribble(
    ~index, ~ v1,
    1,   "a",
    2,   "a",
    3,   "d",
    4,   "f",
    5,   "f",
    6,   "g",
    7,   "a",
    8,   "a",
    9,   "x",
    10,  "d",
    11,  "d",
    12,  "x",
    13,  "e",
    14,  "a",
    15,  "a",
    16,  "d",
    17,  "c",
    18,  "f",
    19,  "e",
    20,  "e",
    21,  "c") 
    
    df %>% 
      group_split(ceiling(index / 6), .keep = FALSE) %>% 
      invoke(cbindPad, .)
    

    我们得到:

    index v1 index v1 index v1 index   v1
    1     1  a     7  a    13  e    19    e
    2     2  a     8  a    14  a    20    e
    3     3  d     9  x    15  a    21    c
    4     4  f    10  d    16  d    NA <NA>
    5     5  f    11  d    17  c    NA <NA>
    6     6  g    12  x    18  f    NA <NA>
    

    【讨论】:

    • 这个结果在一个“页面”上是 4 宽。如何修改以获得 2 宽或其他宽度?
    • 更改 6:使用 12。根据您的目标,像这样操作 datframe 可能不是最佳的;考虑查看 knitr::kable 或 DT::datatable 进行显示
    猜你喜欢
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多