【问题标题】:Restructure / reshape data frame ( r )重组/重塑数据框( r )
【发布时间】:2016-04-14 03:28:14
【问题描述】:

我的数据集对从事项目工作的人进行了反复观察。我需要一个包含两列的数据框,其中列出了每个人和时间点的项目“组合”。让我用一个例子来解释:

这是我的数据:

ID    Week    Project    
01    1       101
01    1       102 
01    1       103
01    2       101
01    2       102
02    1       101
02    1       102
02    2       101

个人 1 (ID = 1) 在第 1 周参与了三个项目。这意味着此人在这一周有六种可能的项目组合(project_i 和 project_j)。

这就是我需要的

ID   Week    Project_i  Project_j
01    1      101        101
01    1      101        102
01    1      101        103
01    1      102        101
01    1      102        102    
01    1      102        103
01    1      103        101
01    1      103        102
01    1      103        103
01    2      101        101
01    2      101        102
01    2      102        101
01    2      102        102
02    1      101        101
02    1      101        102
02    1      102        101
02    1      102        102
02    2      101        101

每周只有一个项目的败诉不是问题。

我已经尝试了基本的 r 和 reshape2,但我无法弄清楚。

【问题讨论】:

  • 现在,我没有在同一行中包含相同的项目 ID(即 101 101)

标签: r reshape2


【解决方案1】:

这是一种方法:

library(data.table)
setDT(DT)

DT[, CJ(P1 = Project, P2 = Project)[P1 != P2], by=.(ID, Week)]

    ID Week  P1  P2
 1:  1    1 101 102
 2:  1    1 101 103
 3:  1    1 102 101
 4:  1    1 102 103
 5:  1    1 103 101
 6:  1    1 103 102
 7:  1    2 101 102
 8:  1    2 102 101
 9:  2    1 101 102
10:  2    1 102 101

CJ 是两个向量的笛卡尔连接,取所有组合。

如果您不想同时使用 (101,102) 和 (102,101),请使用 P1 > P2 而不是 P1 != P2。哦,OP改变了问题......所以使用P1 <= P2

【讨论】:

  • 这似乎可行,但 r 仍在运行。对于 200 万次观测,您认为这需要很长时间(或根本可行)吗?
  • @HJ_r 可能不是。你需要考虑你试图解决的组合问题。您可以键入combos = DT[, .(n = .N*(.N-1L)), by = .(ID, Week)] 以查看问题的大小。 combos[, sum(n)]会显示结果中的总行数,也可以查看combos[, summary(n)]combos[, hist(n)]等。
【解决方案2】:

这是一个使用dplyrtidyr 的解决方案。关键步骤是tidyr::complete()结合dplyr::group_by()

library(dplyr)
library(tidyr)

d %>% 
  rename(Project_i = Project) %>%
  mutate(Project_j = Project_i) %>% 
  group_by(ID, Week) %>%
  complete(Project_i, Project_j) %>%
  filter(Project_i != Project_j)

【讨论】:

    【解决方案3】:

    这是使用expand.grid 的基本选项:

    do.call(rbind, lapply(split(df, paste(df$ID, df$Week)), function(x){
        x2 <- expand.grid(ID = unique(x$ID), 
                          Week = unique(x$Week), 
                          Project_i = unique(x$Project), 
                          Project_j = unique(x$Project))
        # omit if 101 102 is different from 102 101; make `<` if 101 101 not possible
        x2[x2$Project_i <= x2$Project_j,]
    }))
    
    #       ID Week Project_i Project_j
    # 1 1.1  1    1       101       101
    # 1 1.4  1    1       101       102
    # 1 1.5  1    1       102       102
    # 1 1.7  1    1       101       103
    # 1 1.8  1    1       102       103
    # 1 1.9  1    1       103       103
    # 1 2.1  1    2       101       101
    # 1 2.3  1    2       101       102
    # 1 2.4  1    2       102       102
    # 2 1.1  2    1       101       101
    # 2 1.3  2    1       101       102
    # 2 1.4  2    1       102       102
    # 2 2    2    2       101       101
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      • 2010-12-04
      • 2017-02-11
      相关资源
      最近更新 更多