计算逗号分隔字符串中的唯一值

时间:2017-05-12 06:09:44

标签: r string unique

数据帧的前两列构成一个复合键,其中包含char类型的列,其中包含逗号分隔的整数。我的目标是创建一个包含字符串中唯一整数计数的列。 我知道使用str_split_fixed将字符串转换为列然后计算唯一值的方法,但由于字符串的长度,添加了大量列并且一切都滞后。还有其他方法吗? 实际数据集包含500k行和53列。 样本数据集:
DF

c1      c2    c3  
aa      11   1,13,4,5,4,7,9    
bb      22   2,5,2,4,5,7,11,     
cc      33   11,14,3,1,    
dd      44   1,1,2,4,5,6,15,    
ee      55   4,3,3,1,14,17,

期望的输出:

c1        c2             c3             c4  
------ | ------   | ------          | -----   
aa     | 11       | 1,13,4,5,4,7,9  |  6    
------ | ------   | ------          | -----   
bb     | 22       | 2,5,2,4,5,7,11, |  5   
------ | ------   | ------          | -----   
cc     | 33       | 11,14,3,1,      |  4   
------ | ------   | ------          | -----   
dd     | 44       | 1,1,2,4,5,6,15, |  6       
------ | ------   | ------          | -----   
ee     | 55       | 4,3,3,1,7,17,7, |  5    
------ | ------   | ------          | -----  

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:5)

strsplituniqueN包中的data.table一起使用 -

df$c4 <- sapply(strsplit(df$c3,','), uniqueN)

给出:

> df
  c1 c2              c3 c4
1 aa 11  1,13,4,5,4,7,9  6
2 bb 22 2,5,2,4,5,7,11,  5
3 cc 33      11,14,3,1,  4
4 dd 44 1,1,2,4,5,6,15,  6
5 ee 55  4,3,3,1,14,17,  5

注意:如果df$c3是因子变量,请将其打包在as.character中:sapply(strsplit(as.character(df$c3), ','), uniqueN)

另一个用于创建df$c4的基础R替代方案:

sapply(regmatches(df$c3, gregexpr('\\d+', df$c3)), function(x) length(unique(x)))

tidyverse替代方案:

library(dplyr)
library(tidyr)
df %>% 
  separate_rows(c3) %>% 
  filter(c3 != '') %>% 
  group_by(c1) %>% 
  summarise(c4 = n_distinct(c3)) %>% 
  left_join(df, .)

答案 1 :(得分:4)

我们可以使用stri_extract提取所有数字,然后循环浏览list,找到lengthunique元素

library(stringi)
df1$Count <- sapply(stri_extract_all_regex(df1$col3, "[0-9]+"), 
                     function(x) length(unique(x)))

答案 2 :(得分:3)

假设您的df如下所示:

df <- c("1,13,4,5,4,7,9,", "2,5,2,4,5,7,11,","11,14,3,1,4,"," 1,1,2,4,5,6,15,","4,6,3,3,1,14,17,14,")
df <- gsub("\\s+|,$","",df) ##Removal of unnecssary spaces and trailing commas

然后你可以使用 baseR

unlist(lapply(strsplit(df,split=","),function(x)length(unique(x))))

结果如下:

[1] 6 5 5 6 6