【问题标题】:nested if else for string search嵌套 if else 用于字符串搜索
【发布时间】:2015-02-23 00:18:28
【问题描述】:

可重现的数据集

   data1 <- data.frame(ID = c(1,2), Description = c("Chiquita","Chiquita mazamorra"), Max = c(200,125))
   data2 <- data.frame(ID = c(1,2,3,4,5,6,7), Description = c("Chiquita mini", "Chiquita Oriville","Chiquita 24h","Manzano Chiquita 5j...","Chiquita mazamorra 1,2h..","Chiquita mazamorra Buro","Chiquita AM 2F"), Max = c(24,110,80,90,134,123,210))

我有一个数据集data1,如下图

  Id     Description            Max
  1      Chiquita               200
  2      Chiquita mazamorra     125

我还有另一个数据集data2,如下图

  Id     Description                   Actual
  1      Chiquita mini                 24
  2      Chiquita Oriville             110
  3      Chiquita 24h                  80
  4      Manzano Chiquita 5j...        90
  5      Chiquita mazamorra 1,2h...    134
  6      Chiquita mazamorra Buro       123
  7      Chiquita AM 2F                210
  8      Chiquita.....                 124
  9      Chiquita(P)                   213
  10     Chiquita, mazamorra, S        188                   

If 语句应检查 Data2 描述是否在 data2$Description Chiquita mazamorra 中包含此字符,如果是,则检查 Data2$Actual > Data1$Max。如果是,那么结果 == 好,否则小。请注意,在 Chiquita mazamorra 之后可能还有其他字符,例如 Chiquita mazamorra 1,2h.. 这没关系,但不是 Chiquita mazamorra Buro

类似地,另一个 ifelse 应该检查 Data2 描述是否包含 Chiquita,如果是,则检查 Data2$Actual > Data1$Max。如果是,那么结果 == 好,否则小。在 Chiquita 之后可以有其他字符,例如 Chiquita 24hChiquita AM 2F 这些都可以,但不是 Chiquita miniChiquita Oriville

这是最终期望的输出(data2)

  Id     Description                   Actual      Result
  1      Chiquita mini                 24          NA
  2      Chiquita Oriville             110         NA
  3      Chiquita 24h                  80          Small
  4      Manzano Chiquita 5j...        90          NA
  5      Chiquita mazamorra 1,2h...    134         Good         
  7      Chiquita mazamorra Buro       123         NA
  6      Chiquita AM 2F                210         Good
  8      Chiquita.....                 124         Small
  9      Chiquita(P)                   213         NA
  10     Chiquita, mazamorra, S        188         Good

我知道这可以使用 grepl 和 ifelse 语句的组合来完成,我不是很自信?也许有更好的方法可以做到这一点,我不知道,我很困惑。需要帮忙。

【问题讨论】:

标签: r if-statement dplyr grepl


【解决方案1】:

以下是解决方案的概要

data1 <- read.csv(text=
"Id,Description,Max
1,Chiquita,200
2,Chiquita mazamorra,125")

data2 <- read.csv(text=
"Id,Description,Actual
1,Chiquita mini,24
2,Chiquita Oriville,110
3,Chiquita 24h,80
4,Manzano Chiquita 5j,90
5,Chiquita mazamorra 12h,134
6,Chiquita mazamorra Buro,123
7,Chiquita AM 2F,210")


# start by trimming the description to the first few words 
# that don't start with a number
data2$Description_trimmed <- gsub('\\s+\\d.*$','',data2$Description)

# initialize the output field
data2$Results <- NA

# loop while there are missing values in data$Results
while(any(is.na(data2$Results))){

    # identify records that still need to be calculated
    indx <- is.na(data2$Results)

    # calculate the result based on the current trimmed description
    data2[indx,'Results']  <-  ifelse(
                data2[indx,'Actual']  < 
                    data1[match(data2[indx,'Description_trimmed'],
                                data1[    ,'Description']),
                          "Max"],
                'Good',
                'Small')

    # trim the last word from Description_trimmed
    data2$Description_trimmed <- gsub('(^| +)[^ ]*$','',data2$Description_trimmed)

    # stop if the remaining trimmed descriptions are empty
    if(all(grepl('^\\s*$',data2$Description_trimmed)))
        break
}

data2
#>   Id             Description Actual Description_trimmed Results
#> 1  1           Chiquita mini     24                        Good
#> 2  2       Chiquita Oriville    110                        Good
#> 3  3            Chiquita 24h     80                        Good
#> 4  4     Manzano Chiquita 5j     90                        <NA>
#> 5  5  Chiquita mazamorra 12h    134                       Small
#> 6  6 Chiquita mazamorra Buro    123                        Good
#> 7  7          Chiquita AM 2F    210                       Small

(BTY,此解决方案在每个循环中计算 is.na(data$Results) 两次,而您实际上只需要计算一次 - 我是为了便于阅读而不是这方面的效率......)

【讨论】:

  • 尝试了您的解决方案,代码进入无限循环,我也对您在建议的解决方案中引用的一些变量感到困惑,例如 data$Results ??我假设这是 data2$Results :)
  • :) 修复工作有效,但逻辑剂量选择描述有尾随的情况......例如第 8 行,Data2,因为此观察属于 data1 中的规则 1(data1,第 1 行),我希望结果会显示很小或很好,但现在它显示 NA :) ,类似地,当有 a 时,其间是第 10 行 data2。很抱歉,这是一个非常疯狂的数据集,非常感谢您的帮助。
  • 您必须为您的数据集定制正则表达式。例如,将'\\s+\\d.*$' 替换为'\\s+[0-9.].*$' 可能有助于解决尾随'...' 问题。我建议尝试regex101.com 并使用适合您的字符串测试一些表达式。 :)
猜你喜欢
  • 2013-05-15
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-14
相关资源
最近更新 更多