如果另一列中的内容包含字符串

时间:2017-12-07 02:35:22

标签: r

我正在使用大型数据集,我想确定包含文本字符串的列是否通过了逻辑测试,我可以在以后对其进行子集化。目前,我正在尝试为每一行构建测试列。测试基于单元格是否包含少于2个相关字符,但我想在实际单元格中保留完整的字符集。以下是我想要做的简化示例:

假设我有以下数据框:

df <- data.frame(matrix(NA, nrow = 5, ncol = 1))
colnames(df) <- "test"
df$test <- c("one", "two", "three", "one", "onetwo")
df$hyp <- ("two", "one", "onetwo", "one", "two")
df$testcount <- sapply(df$test, str_length)
df$hypcount <- sapply(df$hyp, str_length)
df

    test    hyp testcount hypcount
1    one    two         3        3
2    two    one         3        3
3  three onetwo         5        6
4    one    one         3        3
5 onetwo    two         6        3

我想识别一个文本字符串,比如“两个”,如果test列或hyp列中有一行(取决于我正在运行的测试。我不想要这个在两列上运行)包含字符串(虽然与字符串不同),然后我希望同一行减去我从testcounthypcount标识的字符串中的字符数列。

例如,如果我在test列中的文本字符串“two”上运行此函数,那么我应该得到以下输出:

    test    hyp testcount hypcount
1    one    two         3        3
2    two    one         0        3
3  three onetwo         5        6
4    one    one         3        3
5 onetwo    two         3        3

如果我在hyp列上运行此操作,那么我应该得到以下输出:

    test    hyp testcount hypcount
1    one    two         3        0
2    two    one         3        3
3  three onetwo         5        3
4    one    one         3        3
5 onetwo    two         6        0

我尝试了三种方法。首先,我尝试使用if函数有条件地运行替换(在此测试中,我测试了字符串“one”而不是“two”):

if(grepl("one", df$test)) {
  df[which(grepl("one", df$test)), ]$testcount = df[which(grepl("one", df$test)), ]$testcount - 3
  }

但是这会返回警告: “在if(grepl(”one“,df $ test)){:   条件的长度> 1,只使用第一个元素“

这导致正确替换字符串“one”,而不是字符串“two”。此外,如果我在hyp列中替换字符串“two”,则该函数可以工作,但是如果我运行字符串“one”的替换则不行。我怀疑这是因为它只在第一行运行测试,如果是,则检查整个数据帧。

接下来我尝试在lapply函数中运行该函数:

df <- data.frame(lapply(df, function(x) {
  if(grepl("one", df$test)) {
    df[which(grepl("one", df$test)), ]$testcount = df[which(grepl("one", df$test)), ]$testcount - 3
  }}))

虽然我不完全理解为什么,但这也行不通。不知何故,它最终返回输出:

  test hyp testcount hypcount
1    0   0         0        0
2    0   0         0        0
3    3   3         3        3

最后,我尝试将其作为ifelse操作运行(这里我切换到替换字符串“two”,所以我不会错误地认为该函数适用于所有行):

df$testcount <- ifelse(grepl("two", df$test), (df[which(grepl("two", df$test)), ]$testcount = df[which(grepl("two", df$test)), ]$testcount - 3))

奇怪的是,这在我几天前第一次应用它时起作用了。我测试了它的字符串“two”,“on”和“one”,它运行正常。现在,当我开始将它应用于我的实际数据时,它不起作用。此外,当我回到测试中看看出了什么问题时,它就不再起作用了。它只是返回错误:   “ifelse错误(grepl(”two“,df $ test),(df [which(grepl(”two“,df $ test)),:   缺少参数“no”,没有默认值“

我尝试了两种解决方案。首先,我尝试在“no”参数中添加一个对我的数据没有影响的语句:

 df$testcount <- ifelse(grepl("two", df$test), (df[which(grepl("two", df$test)), ]$testcount = df[which(grepl("two", df$test)), ]$testcount - 3), T)

但是,这会导致它返回输出:

    test    hyp testcount hypcount
1    one    two         1        3
2    two    one         3        3
3  three onetwo         1        6
4    one    one         1        3
5 onetwo    two         0        3

接下来我尝试用一​​个有意义的“否”参数代替:

 df$testcount <- ifelse(grepl("two", df$test), (df[which(grepl("two", df$test)), ]$testcount = df[which(grepl("two", df$test)), ]$testcount - 3), (df[which(grepl("two", df$test)), ]$testcount = df[which(grepl("two", df$test)), ]$testcount))

但现在它返回输出:

    test    hyp testcount hypcount
1    one    two        -3        3
2    two    one         0        3
3  three onetwo        -3        6
4    one    one         0        3
5 onetwo    two        -3        3

我不明白这个输出。

我的问题是,任何人都可以帮助我理解为什么这不起作用,并提供解决方案?提前谢谢!

2 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解您的问题,但以下内容再现了您对这两个测试用例的预期结果。

db.collection.find({"_id": { "$gt": ObjectId.fromDate(new Date('2017-10-01'))}})

另外,你说&#34;包含字符串(虽然与字符串不同)&#34; ,但对于包含&#34; onetwo&#34;的条目。你做减去计数值。那么你完成的比赛是完整的吗?

答案 1 :(得分:0)

尝试此功能:

subtract_match <- function(column1, column2, text, df) {
  df2 <- df
  df2[, column2] <- ifelse(grepl(text, df[, column1]), 
                           df[, column2] - nchar(text), 
                           df[, column2])
  df2
}

subtract_match("test", "testcount", "two", df1)

    test    hyp testcount hypcount
1    one    two         3        3
2    two    one         0        3
3  three onetwo         5        6
4    one    one         3        3
5 onetwo    two         3        3

subtract_match("hyp", "hypcount", "two", df1)

    test    hyp testcount hypcount
1    one    two         3        0
2    two    one         3        3
3  three onetwo         5        3
4    one    one         3        3
5 onetwo    two         6        0