成对组合以及data.table中的计数

时间:2015-06-08 06:04:31

标签: r data.table

我有一个data.frame d,如下所示。

d <- structure(list(sno = 1:7, list = c("SD1, SD44, SD384, SD32", 
"SD23, SD1, SD567", "SD42, SD345, SD183", "SD345, SD340, SD387", 
"SD455, SD86, SD39", "SD12, SD315, SD387", "SD32, SD1, SD40")), .Names = c("sno", 
"list"), row.names = c(NA, -7L), class = "data.frame")

d
  sno                   list
1   1 SD1, SD44, SD384, SD32
2   2       SD23, SD1, SD567
3   3     SD42, SD345, SD183
4   4    SD345, SD340, SD387
5   5      SD455, SD86, SD39
6   6     SD12, SD315, SD387
7   7        SD32, SD1, SD40

我希望获得由&#34;,&#34;分隔的所有字符串的成对组合。在d$list

我可以使用lapply获取它,如下所示。

d2 <- strsplit(d$list, split = ", ")
d2 <- lapply(d2, function(x) as.data.frame(t(combn(x, m=2))))
library(data.table)
d2 <- rbindlist(d2)

我想要将d$list中每个组的计数以及合并列表d2作为新列。如何使用data.table

执行此操作
library(stringi)
stri_count_fixed(d$list,", ")

所需的输出如下

out <- structure(list(V1 = structure(c(1L, 1L, 1L, 3L, 3L, 2L, 4L, 4L, 
1L, 6L, 6L, 5L, 5L, 5L, 7L, 8L, 8L, 9L, 10L, 10L, 11L, 12L, 12L, 
1L), .Label = c("SD1", "SD384", "SD44", "SD23", "SD345", "SD42", 
"SD340", "SD455", "SD86", "SD12", "SD315", "SD32"), class = "factor"), 
    V2 = structure(c(3L, 2L, 1L, 2L, 1L, 1L, 4L, 5L, 5L, 7L, 
    6L, 6L, 8L, 9L, 9L, 11L, 10L, 10L, 12L, 9L, 9L, 4L, 13L, 
    13L), .Label = c("SD32", "SD384", "SD44", "SD1", "SD567", 
    "SD183", "SD345", "SD340", "SD387", "SD39", "SD86", "SD315", 
    "SD40"), class = "factor"), count = c(4, 4, 4, 4, 4, 4, 3, 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3)), .Names = c("V1", 
"V2", "count"), row.names = c(NA, -24L), class = "data.frame")


out 
      V1    V2 count
1    SD1  SD44     4
2    SD1 SD384     4
3    SD1  SD32     4
4   SD44 SD384     4
5   SD44  SD32     4
6  SD384  SD32     4
7   SD23   SD1     3
8   SD23 SD567     3
9    SD1 SD567     3
10  SD42 SD345     3
11  SD42 SD183     3
12 SD345 SD183     3
13 SD345 SD340     3
14 SD345 SD387     3
15 SD340 SD387     3
16 SD455  SD86     3
17 SD455  SD39     3
18  SD86  SD39     3
19  SD12 SD315     3
20  SD12 SD387     3
21 SD315 SD387     3
22  SD32   SD1     3
23  SD32  SD40     3
24   SD1  SD40     3

1 个答案:

答案 0 :(得分:2)

使用gsub我们可以删除除分隔符(,)以外的所有字符,使用nchar计算字符数,添加1以获取字数,并使用transform创建一个新列“计数”。使用cSplit中的splitstackshape,我们可以将“列表”列拆分为,,方向指定为long,我们会重新格式化数据集。加载splitstackshape也会加载data.table,因此我们可以使用data.table聚合方法。通过'sno'和'Count'(.(sno, Count))分组,我们得到'{1}}'list',根据来自{{的交替值创建两列('V1','V2') 1}}输出,并将'sno'列指定为NULL(如果不需要)

combn

或修改您的代码,我们使用combn在'd2'中创建'计数'列,并按照帖子中的说明,执行library(splitstackshape) d1 <- transform(d, Count=nchar(gsub('[^,]', '', list))+1L) cSplit(d1, 'list', ', ', 'long')[, { tmp <- combn(as.character(list), 2) list(V1=tmp[c(TRUE, FALSE)], V2= tmp[c(FALSE, TRUE)]) }, .(sno, Count)][, sno:= NULL] # Count V1 V2 #1: 4 SD1 SD44 #2: 4 SD1 SD384 #3: 4 SD1 SD32 #4: 4 SD44 SD384 #5: 4 SD44 SD32 #6: 4 SD384 SD32 #7: 3 SD23 SD1 #8: 3 SD23 SD567 #9: 3 SD1 SD567 #10: 3 SD42 SD345 #11: 3 SD42 SD183 #12: 3 SD345 SD183 #13: 3 SD345 SD340 #14: 3 SD345 SD387 #15: 3 SD340 SD387 #16: 3 SD455 SD86 #17: 3 SD455 SD39 #18: 3 SD86 SD39 #19: 3 SD12 SD315 #20: 3 SD12 SD387 #21: 3 SD315 SD387 #22: 3 SD32 SD1 #23: 3 SD32 SD40 #24: 3 SD1 SD40 Map/cbind折叠为单个' data.table'对象。

rbindlist