使用data.table删除字符串的一部分

3

我有一个数据表,其中包含一些字符串。当我发现重复的东西时,我只需要用它们来识别某些行。首先我想要用它来识别特定的行(并创建一个基于此的新变量)。然后我想去掉该部分(在我的示例中为x)。

我知道有一些不使用data.table的解决方案。但是,对我来说,问题在于学习更好地使用data.table,并且我需要%chin%的提高时间性能,这就是为什么我想学习如何在data.table中设置它的原因。

c <- c("a", "b (x)", "c", "d (x)")
d <- c(1, 2, 3, 4)

c_name <- "string"
d_name <- "numeric"

df <- data.frame(c,d)
names(df) <- c(c_name,d_name)
setDT(df)

#Now comes the part where I want to create a new variable "Newvar" that only has text, if no "(x)" is in (%chin%) the string variable c:
df[ !( c %chin% c("(x)")) , Newvar:="had (x)"]
#My code does not work. It just takes All Rows. 

#Next I want to remove all parts with (x) in string var c:
df[ ( c %chin% c("(x)")) , c ]
#this does not work like this. 

我没有收到任何错误消息,但我的最终数据集应该像这样:
#Final data set generation:

# 1) manually searching for (x)
Newvar <- c("", "had (x)","", "had (x)" )
# 2) "renaming" the string variable c
df$string <- gsub("\\(x\\)*", "", df$string)

#so actually the solution should be:
  df$string <- c("a", "b", "c", "d") 

不过在我的实际问题中,我无法用手写任何代码,即使有一辈子的时间 :D


2
提供了一个很好的可重现示例,但请不要在Stack Overflow上发布像rm(list = ls())这样的代码。我不想从您的问题中复制/粘贴代码并意外运行该行。 - Gregor Thomas
哦,抱歉,我会删除它的!非常抱歉,我不知道! - canIchangethis
1个回答

2

%chin%进行全匹配,就像%in%一样,但速度更快。你试图将其用于字符串内的部分匹配。要在字符串中匹配模式,请使用grep(或grepl,它返回一个逻辑值,在这种情况下很好用)。


c
# [1] "a"     "b (x)" "c"     "d (x)"
c %chin% "(x)"
# [1] FALSE FALSE FALSE FALSE
grepl("(x)", c, fixed = TRUE)
# [1] FALSE  TRUE FALSE  TRUE

如果你使用grepl,我认为你的代码将按照你的期望工作。我使用fixed = TRUE是因为我们匹配的是一个确切的模式,而不是正则表达式。
我还觉得奇怪的是,你费尽心思地将c列命名为"string",但你总是使用向量c而不是data.table中的列df$string。我建议修改为:
# old
df[ !( c %chin% c("(x)")) , Newvar:="had (x)"]
# new: use `grepl` instead of `%chin%`, and `string` instead of `c`
df[ !grepl("(x)", string, fixed = TRUE) , Newvar:="had (x)"]

亲爱的Gregor,谢谢。我不知道为什么后来使用c而不是string,我只是为了清晰度引入它,但并没有完全做到。显然neglect(!)也被误用了,因为我显然想要那些有“(x)”这个术语的内容。fixed具体是做什么的?从帮助中得知,“logical. If TRUE, pattern is a string to be matched as is. Overrides all conflicting arguments.”但这是什么意思呢? - canIchangethis
grepl默认使用正则表达式。正则表达式是一种强大的匹配模式的方式,包含许多特殊字符,包括括号。在这里您不需要正则表达式,fixed = TRUE禁用正则表达式,表示您想匹配一个固定的子字符串,而不是一个模式。 - Gregor Thomas
感谢您的解释,@Gregor! - canIchangethis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接