2015-05-11 25 views
3

我需要用于社会结构分析的特定格式的data.frame。如何个体对多个事件一起存在的的data.frame含列表转换:将个人列表转换为R中的成对对象

my.df <- data.frame(individual = c("A","B","C","B","C","D"), 
        time = rep(c("event_01","event_02"), each = 3)) 

    individual  time 
1   A event_01 
2   B event_01 
3   C event_01 
4   B event_02 
5   C event_02 
6   D event_02 

成每个对含occurence data.frame(包括[A,A]; [B,B]等双:

ind_1 ind_2 times 
    A  A  0 
    A  B  1 
    A  C  1 
    A  D  0 
    B  A  1 
    B  B  0 
    B  C  2 
    B  D  1 
    C  A  1 
    C  B  2 
    C  C  0 
    C  D  1 
    D  A  0 
    D  B  1 
    D  C  1 
    D  D  0 
+0

你有你的真实数据只有两种类型的事件? –

+0

Hi @ColonelBeauvel。不,我有更多的二十个事件。 –

回答

8

在基础R,你可以做做到以下几点:

data.frame(as.table(`diag<-`(tcrossprod(table(my.df)), 0))) 
# individual individual.1 Freq 
# 1   A   A 0 
# 2   B   A 1 
# 3   C   A 1 
# 4   D   A 0 
# 5   A   B 1 
# 6   B   B 0 
# 7   C   B 2 
# 8   D   B 1 
# 9   A   C 1 
# 10   B   C 2 
# 11   C   C 0 
# 12   D   C 1 
# 13   A   D 0 
# 14   B   D 1 
# 15   C   D 1 
# 16   D   D 0 

tcrossprod为您提供了以下内容:

> tcrossprod(table(my.df)) 
      individual 
individual A B C D 
     A 1 1 1 0 
     B 1 2 2 1 
     C 1 2 2 1 
     D 0 1 1 1 

这基本上就是你正在寻找的信息,但是你想在一个稍微不同的形式,而不对角线值。

我们可以设置对角线零:

`diag<-`(theOutputFromAbove, 0) 

然后,为了获得长期的形式,诱骗R导入思维所产生的matrixtable使用as.table,并利用data.frame方法为table s。

0

则可以使用data.table

dt_combs <- my.dt[, 
        list(ind_1 = combn(individual, 2)[1, ], 
         ind_2 = combn(individual, 2)[2, ]), 
        by = time] 
dt_ncombs <- dt_combs[, .N, by = c("ind_1", "ind_2")] 
dt_ncombs_inverted <- copy(dt_ncombs) 
dt_ncombs_inverted[, temp := ind_1] 
dt_ncombs_inverted[, ind_1 := ind_2] 
dt_ncombs_inverted[, ind_2 := temp] 
dt_ncombs_inverted[, temp := NULL] 
dt_ncombs <- rbind(dt_ncombs, dt_ncombs_inverted) 
dt_allcombs <- data.table(expand.grid(
    ind_1 = my.dt[, unique(individual)], 
    ind_2 = my.dt[, unique(individual)] 
)) 
dt_final <- merge(dt_allcombs, 
        dt_ncombs, 
        all.x = TRUE, 
        by = c("ind_1", "ind_2")) 
dt_final[is.na(N), N := 0] 
dt_final 
+0

嗨@MichelleUsuilli !.感谢您的回应,但是您的最终输出与我的输出不匹配。请比较它们。 –

+0

是的。我只是添加了一个额外的步骤,现在它应该可以工作。 –

4

你可以这样做:

创建新data.frame的第2个变量:

df2 <- expand.grid(ind_2=levels(my.df$individual), ind_1=levels(my.df$individual))[, 2:1] 

把值设为0的相同的对个人的:

df2$times[df2[, 1]==df2[, 2]] <- 0 

参见其他独特组合:

comb_diff <- combn(levels(my.df$individual), 2) 

计算每个唯一组合被发现在一起的时光:

times_uni <- apply(comb_diff, 2, function(inds){ 
            sum(table(my.df$time[my.df$individual %in% inds])==2) 
           }) 

最后填充新data.frame:

df2$times[match(c(paste0(comb_diff[1,], comb_diff[2,]), paste0(comb_diff[2, ], comb_diff[1, ])), paste0(df2[, 1],df2[, 2]))] <- rep(times_uni, 2) 

df2 
# ind_1 ind_2 times 
#1  A  A  0 
#2  A  B  1 
#3  A  C  1 
#4  A  D  0 
#5  B  A  1 
#6  B  B  0 
#7  B  C  2 
#8  B  D  1 
#9  C  A  1 
#10  C  B  2 
#11  C  C  0 
#12  C  D  1 
#13  D  A  0 
#14  D  B  1 
#15  D  C  1 
#16  D  D  0 
相关问题