【问题标题】:How to format a pivot like table that includes records for all time and id values?如何格式化包含所有时间和 id 值记录的数据透视表?
【发布时间】:2013-02-28 19:11:37
【问题描述】:

我正在用 3 列在 R 中收集日志:
周、探测和观察次数。
没有观察就没有记录。

week=c(1,2,2,4)  
probe=c("A","C","B","C")  
obs=c(2,4,3,1)
logs=data.frame(week,probe,obs)

logs

week probe obs  
1     A   2
2     C   4
2     B   3
4     C   1

我想重新格式化数据,使其包括所有周和所有探测,即使没有观察,它看起来像这样:

week probe obs  
1     A   2  
1     B   0  
1     C   0  
1     D   0  
2     A   0  
2     B   0  
2     C   3  
2     D   4  
3     A   0  
3     B   0  
3     C   0  
3     D   0  
4     A   0  
4     B   0  
4     C   1  
4     D   0  

我这里有所有探测的列表:

allprobes=c("A","B","C","D")

我想看看这几周:

allweeks=c(1:4)

我一直在研究熔化、铸造、重塑,但我只能设法每个 id 或每个月获得 1 行... 因为我实际上想保留日志的原始格式。 一开始似乎很容易,但我现在卡住了...... 有关如何以这种方式格式化数据的任何建议?

非常感谢您的帮助。

【问题讨论】:

    标签: r reshape


    【解决方案1】:

    基础 R 中的两个选项:

    使用expand.gridmerge

    > fullFrame <- expand.grid(allweeks, allprobes)
    > names(fullFrame) <- c("week", "probe")
    > merge(fullFrame, logs, all = TRUE)
       week probe obs
    1     1     A   2
    2     1     B  NA
    3     1     C  NA
    4     1     D  NA
    5     2     A  NA
    6     2     B   3
    7     2     C   4
    8     2     D  NA
    9     3     A  NA
    10    3     B  NA
    11    3     C  NA
    12    3     D  NA
    13    4     A  NA
    14    4     B  NA
    15    4     C   1
    16    4     D  NA
    

    expand.grid 将为您的“allprobes”和“allweeks”对象的所有可能组合创建一个data.frame。然后,当使用merge 时,我们重命名该新data.frame 的列以匹配您的“日志”data.frame 中的相关列。参数all = TRUE 告诉mergeNA 填充缺失值。

    如果您想要零而不是 NA,请执行以下操作:

    fullFrame <- expand.grid(allweeks, allprobes)
    names(fullFrame) <- c("week", "probe")
    finalLogs <- merge(fullFrame, logs, all = TRUE)
    finalLogs[is.na(finalLogs)] <- 0
    

    将“week”和“probe”转换为因子后使用xtabs

    如果您将“周”和“探测”转换为包含所有相关级别的因子,那么您可以简单地使用包裹在data.frame 中的xtabs

    logs$week <- factor(logs$week, levels=c(1, 2, 3, 4))
    logs$probe <- factor(logs$probe, levels=c("A", "B", "C", "D"))
    data.frame(xtabs(obs ~ week + probe, logs))
    #    week probe Freq
    # 1     1     A    2
    # 2     2     A    0
    # 3     3     A    0
    # 4     4     A    0
    # 5     1     B    0
    # 6     2     B    3
    # 7     3     B    0
    # 8     4     B    0
    # 9     1     C    0
    # 10    2     C    4
    # 11    3     C    0
    # 12    4     C    1
    # 13    1     D    0
    # 14    2     D    0
    # 15    3     D    0
    # 16    4     D    0
    

    【讨论】:

      【解决方案2】:

      tidyr 包中的complete 函数是一个很好的实用工具:

      # get all the levels in the factor
      logs$probe = factor(logs$probe, levels = allprobes)
      logs$week = factor(logs$week, levels = 1:4)
      
      tidyr::complete(logs, week, probe, fill = list(obs = 0))
      # # A tibble: 16 × 3
      #      week  probe   obs
      #    <fctr> <fctr> <dbl>
      # 1       1      A     2
      # 2       1      B     0
      # 3       1      C     0
      # 4       1      D     0
      # 5       2      A     0
      # 6       2      B     3
      # 7       2      C     4
      # 8       2      D     0
      # 9       3      A     0
      # 10      3      B     0
      # 11      3      C     0
      # 12      3      D     0
      # 13      4      A     0
      # 14      4      B     0
      # 15      4      C     1
      # 16      4      D     0
      

      【讨论】:

        猜你喜欢
        • 2021-12-13
        • 1970-01-01
        • 1970-01-01
        • 2021-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-08
        相关资源
        最近更新 更多