【发布时间】:2018-05-21 01:33:30
【问题描述】:
我正在处理一个大型数据集,我想确定包含文本字符串的列是否通过了逻辑测试,我可以稍后将其子集化。目前,我正在尝试为每一行构建测试列。测试基于单元格是否包含少于 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
我想识别一个文本字符串,例如“two”,以及 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”,没有默认值”
我已经尝试了两种解决方案。首先,我尝试在“否”参数中添加一个不会影响我的数据的语句:
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
我不明白这个输出。
我的问题是,谁能帮助我理解为什么这不起作用并提供解决方案?提前致谢!
【问题讨论】:
-
“我希望同一行减去我识别的字符串中的字符数”。在您的第一个示例中,
onetwo包含字符串two,因此您不应该从testcount = 6中减去 6(onetwo的长度)以获得零吗? -
好的,我从您下面的评论中看到“字符串”是匹配字符串(两个),而不是匹配字符串(一个两个)。
标签: r