我正在使用大型数据集,我想确定包含文本字符串的列是否通过了逻辑测试,我可以在以后对其进行子集化。目前,我正在尝试为每一行构建测试列。测试基于单元格是否包含少于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
列中有一行(取决于我正在运行的测试。我不想要这个在两列上运行)包含字符串(虽然与字符串不同),然后我希望同一行减去我从testcount
或hypcount
标识的字符串中的字符数列。
例如,如果我在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
我不明白这个输出。
我的问题是,任何人都可以帮助我理解为什么这不起作用,并提供解决方案?提前谢谢!
答案 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