R 为每个ID在列中标识级别的双向组合

R 为每个ID在列中标识级别的双向组合,r,R,我想确定一列中的级别的双向组合,该列按id和Date变量分组。基本上,我希望每个人每天都有一对独特的字母 我有一个如下所示的数据帧: in_df <- data.frame(id = c(1,1,1,1,1,2,2,3), Date = as.Date(c("2019-01-01", "2019-01-01", "2019-01-01", "2019-01-02", &

我想确定一列中的级别的双向组合,该列按
id
Date
变量分组。基本上,我希望每个人每天都有一对独特的字母

我有一个如下所示的数据帧:

in_df <- data.frame(id = c(1,1,1,1,1,2,2,3), 
                    Date = as.Date(c("2019-01-01", "2019-01-01", "2019-01-01", "2019-01-02", "2019-01-02", "2019-01-01", "2019-01-01", "2019-01-01")), 
                    letter = c("A", "B", "C", "A", "B", "A", "D", "B")) 

in_df
  id       Date letter
1  1 2019-01-01      A
2  1 2019-01-01      B
3  1 2019-01-01      C
4  1 2019-01-02      A
5  1 2019-01-02      B
6  2 2019-01-01      A
7  2 2019-01-01      D
8  3 2019-01-01      B
out_df
  id       Date letter_1 letter_2
1  1 2019-01-01        A        B
2  1 2019-01-01        A        C
3  1 2019-01-01        B        C
4  1 2019-01-02        A        B
5  2 2019-01-01        A        D
6  3 2019-01-01        B        NA
因此,第一个
id
和第一个
Date
有字母A、B和C。我想要这三个字母中的每一对都是唯一的。顺序并不重要,所以切换到
字母1
字母2
是一样的

我已经使用了
expand.grid
combn
,但这两种方法似乎都不适合此任务

编辑


我还遇到过这样的情况,即每个
id
/
Date
只有一行,因此使用combn会给我
combn中的错误(字母,m=2):n
。我如何添加一个if大小写,使
字母_2
得到一个NA?(我还更新了上面的dfs以解决此问题)

我们可以使用
拆分
合并

do.call('rbind', 
        lapply(split(in_df, list(in_df$id, in_df$Date), drop = TRUE), 
               FUN = function(d) 
                 cbind.data.frame(unique(d[c('id', 'Date')]), 
                                  data.frame(t(
                                    if(length(d$letter) > 1){
                                      combn(d$letter, 2)    
                                    }else{
                                      matrix(c(d$letter, NA), nrow = 2)
                                    })))))


#                id       Date X1 X2
# 1.2019-01-01.1  1 2019-01-01  A  B
# 1.2019-01-01.2  1 2019-01-01  A  C
# 1.2019-01-01.3  1 2019-01-01  B  C
# 2.2019-01-01    2 2019-01-01  A  D
# 1.2019-01-02    1 2019-01-02  A  B
这样做可能会有帮助。调查以下方面的输出:

(ss <- split(in_df, list(in_df$id, in_df$Date), drop = TRUE))

剩下的部分,我们只是合并数据。您可能需要稍微调整列名。

我认为以下代码可以工作:

库(“dplyr”)
in_df%>%
分组人(id,日期)%>%
变异(
字母_1=combn(字母,2)[1,],
字母2=combn(字母2)[2,]
) %>% 
不同(字母1、字母2)
##A tibble:5 x 4
##组:id,日期[3]
#信函1信函2身份证日期
#                
#1 A B 1 2019-01-01
#2 A C 1 2019-01-01
#3 B C 1 2019-01-01
#4 A B 1 2019-01-02
#5 A D 2 2019-01-01

使用
数据。表

require(data.table); setDT(in_df)

dt = in_df[, data.table(t(combn(letter, m = 2))), .(id, Date)]
输出:

> dt
   id       Date V1 V2
1:  1 2019-01-01  A  B
2:  1 2019-01-01  A  C
3:  1 2019-01-01  B  C
4:  1 2019-01-02  A  B
5:  2 2019-01-01  A  D

您能详细说明一下输出中的第二行和第三行是如何创建的吗?我指的是
letter_1
letter_2
中的值@tmfmnk感谢您的快速响应!我试着再澄清一点,有帮助吗?谢谢!!我也有这样的情况,每个
id
/
Date
只有一行,所以当我使用这个答案时,我得到了combn中的
错误(字母,m=2):n
。我如何才能在if中添加这样的情况,使
字母_2
得到NA?请参见编辑…它使代码变得有点复杂,但它应该可以处理您的情况它已经运行了大约一个小时。也许我的数据对于这种方法来说太大了。这真的很有帮助,谢谢!所有的答案都充分回答了我最初的问题,但这是我唯一可以用来处理稍微复杂一点的实际数据的答案。非常感谢。
> dt
   id       Date V1 V2
1:  1 2019-01-01  A  B
2:  1 2019-01-01  A  C
3:  1 2019-01-01  B  C
4:  1 2019-01-02  A  B
5:  2 2019-01-01  A  D