我有一个这样的数据表:
> x
part colig
1: PR PT, PMDB
2: PMDB PT, PMDB
3: PMDB PT, PMDB
4: PDT PT, PMDB
5: PMDB PT, PMDB
6: PFL PSDB,PFL,PTB
7: PPB PSDB,PFL,PTB
8: PMDB PSDB,PFL,PTB
9: PMDB PSDB,PFL,PTB
10: PPB PSDB,PFL,PTB
> str(x)
Classes ‘data.table’ and 'data.frame': 10 obs. of 2 variables:
$ part : chr "PR" "PMDB" "PMDB" "PDT" ...
$ colig:List of 10
..$ : chr "PT" "PMDB"
..$ : chr "PT" "PMDB"
..$ : chr "PT" "PMDB"
..$ : chr "PT" "PMDB"
..$ : chr "PT" "PMDB"
..$ : chr "PSDB" "PFL" "PTB"
..$ : chr "PSDB" "PFL" "PTB"
..$ : chr "PSDB" "PFL" "PTB"
..$ : chr "PSDB" "PFL" "PTB"
..$ : chr "PSDB" "PFL" "PTB"
- attr(*, ".internal.selfref")=<externalptr>
我想创建一个虚拟变量,当第一个变量包含在第二个变量中时,该变量为1。我想要的输出是:
> x
part colig dummy
1: PR PT, PMDB FALSE
2: PMDB PT, PMDB TRUE
3: PMDB PT, PMDB TRUE
4: PDT PT, PMDB FALSE
5: PMDB PT, PMDB TRUE
6: PFL PSDB,PFL,PTB TRUE
7: PPB PSDB,PFL,PTB FALSE
8: PMDB PSDB,PFL,PTB FALSE
9: PMDB PSDB,PFL,PTB FALSE
10: PPB PSDB,PFL,PTB FALSE
我的问题是访问第二列中列表中的元素。我尝试过这样的事情:
x[, dummy := x[,part] %in% x[, colig]]
或
x[, dummy := x[,part] %in% unlist(x[, colig])]
这两个选项都是错误的。在第一种情况下,dummy总是为FALSE,而在第二种情况下,unlist()命令创建一个列表,其中包含来自所有列表的元素(不仅来自相应的行)。
我也尝试过lapply(比如这里Creating dummy variables in R data.table):
x[, dummy := lapply( x[,part], function(y) y %in% unlist(x[,colig]))]
我认为是正确的,但我遇到速度问题,因为我有很多行。
有没有更快的选择?
答案 0 :(得分:2)
使用grepl
并按“part”的每个值执行:
x[, dummy := grepl(part, colig), by = part]
在第二次阅读OP时,我不确定该列中发生了什么 - 看起来有些元素是列表而其他元素是字符。以上内容适用于角色(您可以在某处挤压lapply(colig, toString)
将列表转换为字符串)。
答案 1 :(得分:1)
尝试stringi
,它应该很快。
library(stringi)
x$dummy = stri_detect(x[,"colig"], fixed=x[,"part"])
# part colig dummy
# 2 PR PT, PMDB FALSE
# 3 PMDB PT, PMDB TRUE
# 4 PMDB PT, PMDB TRUE
# 5 PDT PT, PMDB FALSE
# 6 PMDB PT, PMDB TRUE
# 7 PFL PSDB,PFL,PTB TRUE
# 8 PPB PSDB,PFL,PTB FALSE
# 9 PMDB PSDB,PFL,PTB FALSE
# 10 PMDB PSDB,PFL,PTB FALSE
# 11 PPB PSDB,PFL,PTB FALSE
或data.table
setDT(x)[, dummy := stri_detect(colig, fixed=part)]
如果您看起来像列表和未分离字符串的混合,请尝试类似
的内容setDT(x)[, dummy := any(stri_detect(colig, fixed=part)), by=1:nrow(x)]
答案 2 :(得分:0)
从您的str(x)
输出中,您的数据似乎有些问题。 colig
的前几行似乎没有拆分。换句话说,你可能意味着有两个元素&#34; PT&#34;,&#34; PMDB&#34;而不是单个元素&#34; PT,PMDB&#34;。这可能是问题的一部分。必要时应用strsplit
。
如果您的样本具有代表性,那么只需
apply(x,1,function(x) x$part %in% x$colig)
其中x
只是data.frame
应该足够快。我将x
的更正版本复制到了100000行,这只是在几分之一秒内完成的。