如何在R中创建关系矩阵?

如何在R中创建关系矩阵?,r,matrix,reshape,R,Matrix,Reshape,原始数据: df <- structure(list(ID_client = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), .Label = c("1_", "2_", "3_", "4_"), class = "factor"), Connected = c(1L, 1L, 1L, 0L, 1L, 0L, 1L, 0L), Year = c(2010L, 2010L, 2010L, 2010L, 2015L, 2015L, 2015L, 201

原始数据:

df <- structure(list(ID_client = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), .Label = c("1_", "2_", "3_", "4_"), class = "factor"), Connected = c(1L, 1L, 1L, 0L, 1L, 0L, 1L, 0L), Year = c(2010L, 2010L, 2010L, 2010L, 2015L, 2015L, 2015L, 2015L)), class = "data.frame", row.names = c(NA, -8L))
`ID_client Connected  Year
1_            1      2010
2_            1      2010
3_            1      2010
4_            0      2010
1_            1      2015
2_            0      2015
3_            1      2015
4_            0      2015`
我的目的是创建以下数据:

`Year ID_client    1_   2_   3_   4_
2010     1_       0    1    1    0
2010     2_       1    0    1    0
2010     3_       1    1    0    0
2010     4_       0    0    0    0
2015     1_       0    0    1    0
2015     2_       0    0    0    0
2015     3_       1    0    0    0
2015     4_       0    0    0    0`
换句话说,一个矩阵表示,例如,在2010年,客户端1、2和3被连接,而另一个没有连接。重要的是,我不认为有人与自己有联系。

我尝试了以下代码:

df %>%
  group_by(Year, Connected) %>%
  mutate(temp = rev(ID_client)) %>%
  pivot_wider(names_from = ID_client, 
          values_from = Connected, 
          values_fill = list(Connected = 0)) %>%
  arrange(Year, temp)
这段代码没有复制我需要的东西。相反,这是结果:

`Year ID_client    1_   2_   3_   4_
2010     1_       0    0    1    0
2010     2_       0    1    0    0
2010     3_       1    0    0    0
2010     4_       0    0    0    0
2015     1_       0    0    1    0
2015     2_       0    0    0    0
2015     3_       1    0    0    0
2015     4_       0    0    0    0`

我们可以按
对(u)分组(u)),并创建一个新列(包含ID(u client)值),除当前值外,每组中的(code>Connected=。我们
完成
缺失的级别,然后将数据转换为宽格式

library(tidyverse)

df %>%
  group_by(Year) %>%
  mutate(temp = map(ID_client, ~setdiff(ID_client[Connected == 1], .x))) %>%
  unnest(cols = temp) %>%
  complete(temp = unique(ID_client), fill = list(Connected = 0)) %>%
  mutate(ID_client  = coalesce(as.character(ID_client), temp)) %>%
  pivot_wider(names_from = temp, 
              values_from = Connected, 
              values_fill = list(Connected = 0)) %>%
  arrange(Year, ID_client)

#   Year ID_client  `1_`  `2_`  `3_`  `4_`
#  <int> <chr>     <dbl> <dbl> <dbl> <dbl>
#1  2010 1_            0     1     1     0
#2  2010 2_            1     0     1     0
#3  2010 3_            1     1     0     0
#4  2010 4_            0     0     0     0
#5  2015 1_            0     0     1     0
#6  2015 2_            0     0     0     0
#7  2015 3_            1     0     0     0
#8  2015 4_            0     0     0     0
库(tidyverse)
df%>%
组别(年份)%>%
变异(temp=map(ID_客户端,~setdiff(ID_客户端[Connected==1],.x)))%>%
未测试(cols=温度)%>%
完成(临时=唯一(ID\U客户端),填充=列表(已连接=0))%>%
mutate(ID\u client=coalesce(as.character(ID\u client),temp))%>%
枢轴(名称从=温度,
值_from=已连接,
值\u fill=list(Connected=0))%>%
安排(年份,ID\U客户)
#年份ID_客户'1_``2_``3_``4_`
#           
#1  2010 1_            0     1     1     0
#2  2010 2_            1     0     1     0
#3  2010 3_            1     1     0     0
#4  2010 4_            0     0     0     0
#5  2015 1_            0     0     1     0
#6  2015 2_            0     0     0     0
#7  2015 3_            1     0     0     0
#8  2015 4_            0     0     0     0

您可以使用自连接,即数据与自身的内部连接。通过标记客户组合的信息片段连接:这将是
连接
中的值。由于所需的输出在其对角线上有零,请过滤以删除两个ID相同的情况

正如您所看到的,我还没有转换到
tidyr
pivot\u-wide
版本,但这应该是可以适应的。在
spread
中,指定不应删除未使用的因子级别,以免丢失ID 4

库(dplyr)
图书馆(tidyr)
内部连接(df,df,by=c(“年”,“连接”))%>%
筛选器(已连接==1,ID\u client.x!=ID\u client.y)%>%
排列(key=ID\u client.y,value=Connected,fill=0,drop=F)%>%
安排(年)
#>ID_客户。x年1_u2_u3_4_
#> 1          1_ 2010  0  1  1  0
#> 2          2_ 2010  1  0  1  0
#> 3          3_ 2010  1  1  0  0
#> 4          4_ 2010  0  0  0  0
#> 5          1_ 2015  0  0  1  0
#> 6          2_ 2015  0  0  0  0
#> 7          3_ 2015  1  0  0  0
#> 8          4_ 2015  0  0  0  0

您已经尝试了什么?请显示一些代码,并创建一个。它类似于一个共现表——但每年都要显示一次。我不认为您的代码复制了我想做的事情。当Client_ID为1_时,“1_”列收到值1。相反,它应该是列“2”。你的答案的问题是,它取决于这个特定的玩具数据。例如,如果新数据是df@Miranda ok..我现在就知道了。我先前误解了这个问题。我已经更新了答案。你能检查一下它现在是否工作吗?是的。非常感谢你!