R 将字符列拆分为多个二进制(0/1)列
我有这样一个字符向量:R 将字符列拆分为多个二进制(0/1)列,r,data.table,R,Data.table,我有这样一个字符向量: a您可以从我的“splitstackshape”软件包中尝试cSplit\u e: 一种非常直接的base R方法是将表格与堆栈和strsplit一起使用: table(rev(stack(setNames(strsplit(a, ",", TRUE), seq_along(a))))) # values # ind a b c d # 1 1 1 1 0 # 2 1 1 0 0 # 3 1 1 1 1 基本R-但更长的解决方案: el = uniq
a您可以从我的“splitstackshape”软件包中尝试cSplit\u e
:
一种非常直接的base R方法是将表格
与堆栈
和strsplit
一起使用:
table(rev(stack(setNames(strsplit(a, ",", TRUE), seq_along(a)))))
# values
# ind a b c d
# 1 1 1 1 0
# 2 1 1 0 0
# 3 1 1 1 1
基本R
-但更长的解决方案:
el = unique(unlist(strsplit(a, ',')))
do.call(rbind, lapply(a, function(u) setNames(el %in% strsplit(u,',')[[1]]+0L, el))
# a b c d
#[1,] 1 1 1 0
#[2,] 1 1 0 0
#[3,] 1 1 1 1
x <- strsplit(a,",")
xl <- unique(unlist(x))
t(sapply(x,function(z)table(factor(z,levels=xl))))
另一个复杂的base-R解决方案:
el = unique(unlist(strsplit(a, ',')))
do.call(rbind, lapply(a, function(u) setNames(el %in% strsplit(u,',')[[1]]+0L, el))
# a b c d
#[1,] 1 1 1 0
#[2,] 1 1 0 0
#[3,] 1 1 1 1
x <- strsplit(a,",")
xl <- unique(unlist(x))
t(sapply(x,function(z)table(factor(z,levels=xl))))
另一个选项是tstrsplit()
from:
在我写了这篇文章之后,我注意到博维尔上校的解决方案非常相似,但也许这是一个足够明显的单独的解决方案。没有使用任何软件包
首先,我们将字符串拆分为向量列表,L
,然后计算它们的并集,u
。最后,我们为每个列表元素确定一个二进制向量,并将它们一起rbind
,使用+0
将结果从逻辑转换为数字,并设置列名
L <- strsplit(a, ",")
u <- Reduce(union, L)
m <- do.call(rbind, lapply(L, `%in%`, x = u)) + 0
colnames(m) <- u
添加了最后两行代码可以替换为以下任一行:
do.call(rbind, lapply(lapply(L, factor, levels = u), table))
do.call(rbind, Map(function(x) sapply(u, `%in%`, x), L)) + 0
不幸的是,base R不提供矢量化字符串匹配函数,但是stringi
包提供
library(stringi)
a=c("a,b,c", "a,b", "a,b,c,d")
1*outer(a,unique(unlist(strsplit(a,","))),stri_detect_regex)
# [,1] [,2] [,3] [,4]
#[1,] 1 1 1 0
#[2,] 1 1 0 0
#[3,] 1 1 1 1
我在fastDummies
中成功地使用了dummy\u cols
,它可以非常简单地处理这个问题,并且可以通过变量指定
library(fastDummies)
a <- c("a,b,c", "a,b", "a,b,c,d")
a <- dummy_cols(a, split = ",")
你当然可以使用read.table
加上某种形式的“重塑”方式,但你可能会继续挣扎:-)这是一个惊人的解决方案-但是,我不确定+0L
的功能。你介意解释一下这个答案的逻辑吗?它在a
的每个元素上循环,拆分它们,如果这些拆分的元素位于el
中,则返回一个布尔向量。我只需添加0
即可将布尔向量转换为0/1
向量!哈,不知道stack
是base R中的一个东西。很酷的东西。您的strsplit中的TRUE
在这里似乎没有任何作用。@Frank,除了加快速度之外什么都没有做。看起来不错,
部分看起来很聪明。它是否使用了'0'>0#FALSE
,而其他的都是true,这取决于fill=0
> m
a b c d
[1,] 1 1 1 0
[2,] 1 1 0 0
[3,] 1 1 1 1
do.call(rbind, lapply(lapply(L, factor, levels = u), table))
do.call(rbind, Map(function(x) sapply(u, `%in%`, x), L)) + 0
library(stringi)
a=c("a,b,c", "a,b", "a,b,c,d")
1*outer(a,unique(unlist(strsplit(a,","))),stri_detect_regex)
# [,1] [,2] [,3] [,4]
#[1,] 1 1 1 0
#[2,] 1 1 0 0
#[3,] 1 1 1 1
library(fastDummies)
a <- c("a,b,c", "a,b", "a,b,c,d")
a <- dummy_cols(a, split = ",")
# .data .data_a .data_b .data_c .data_d
# 1 a,b,c 1 1 1 0
# 2 a,b 1 1 0 0
# 3 a,b,c,d 1 1 1 1