计算字符串中逗号分隔的唯一值
Count comma separated unique values in a string
dataframe 的前两列构成了一个复合键,还有一列包含逗号分隔的整数的 char 类型。我的 objective 是创建一个列,其中包含字符串中唯一整数的计数。
我知道使用 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
------ | ------ | ------ | -----
如有任何帮助,我们将不胜感激!
我们可以用stri_extract
提取所有的数字,然后遍历list
,找到unique
个元素的length
library(stringi)
df1$Count <- sapply(stri_extract_all_regex(df1$col3, "[0-9]+"),
function(x) length(unique(x)))
假设您的 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
将 strsplit
与 data.table
软件包中的 uniqueN
一起使用:
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, .)
dataframe 的前两列构成了一个复合键,还有一列包含逗号分隔的整数的 char 类型。我的 objective 是创建一个列,其中包含字符串中唯一整数的计数。
我知道使用 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
------ | ------ | ------ | -----
如有任何帮助,我们将不胜感激!
我们可以用stri_extract
提取所有的数字,然后遍历list
,找到unique
个元素的length
library(stringi)
df1$Count <- sapply(stri_extract_all_regex(df1$col3, "[0-9]+"),
function(x) length(unique(x)))
假设您的 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
将 strsplit
与 data.table
软件包中的 uniqueN
一起使用:
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, .)