1

我有一个这样的数据表:

> 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 (比如这里在 R data.table 中创建虚拟变量):

x[, dummy := lapply( x[,part], function(y) y %in% unlist(x[,colig]))]

我认为这是正确的,但我遇到了速度问题,因为我有很多行。

有没有更快的选择?

4

3 回答 3

2

使用grepl“part”的每个值并执行它:

x[, dummy := grepl(part, colig), by = part]

在第二次阅读 OP 时,我不确定该列中发生了什么 - 看起来有些元素是列表,而其他元素是字符。以上内容适用于字符(您可以挤入lapply(colig, toString)某处将列表转换为字符串)。

于 2015-07-30T20:42:06.897 回答
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)]
于 2015-07-30T19:48:20.767 回答
0

从您的str(x)输出来看,您的数据似乎存在一些问题。的前几行colig似乎没有被拆分。换句话说,您可能意味着拥有两个元素“PT”、“PMDB”,而不是单个元素“PT、PMDB”。这可能是问题的一部分。根据需要申请strsplit

如果您的样本具有代表性,那么只需

apply(x,1,function(x) x$part %in% x$colig)

where xis just adata.frame应该很快。我将您的更正版本复制x到 100000 行,这在几分之一秒内运行。

于 2015-07-30T19:58:54.713 回答