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