首页 > 解决方案 > 我不是来自 grepl 的 gettnig 行号 - 在 R 中执行此操作

问题描述

我正在尝试确定哪一行是数据框中仅包含数字“、”“$”的单元格的第一行:

Assessment Area Offices Offices Deposits as of 6/30/16 Deposits as of 6/30/16 Assessment Area Reviews Assessment Area Reviews Assessment Area Reviews
2 Assessment Area       #       %               $ (000s)                      %              Full Scope           Limited Scope                   TOTAL
3     Ohio County       1   50.0%                $24,451                  52.7%                       1                       0                       1
4     Hart County       1   50.0%                $21,931                  47.3%                       1                       0                       1
5         OVERALL       2    100%                $46,382                 100.0%                       2                       0                       2

此代码确实找到了该行:

grepl("[0-9]",table_1)

但代码返回:

[1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

我只想知道行。

标签: regexgrepl

解决方案


您的数据可能需要进行一些清理,但这对于解决您的问题并不是完全必要的。您希望找到包含美元符号和适当值的第一行。我的解决方案执行以下操作:

  1. 迭代行
  2. 在每一行中,询问是否至少有一个单元格以美元符号开头,后跟数字和逗号的特定组合(将在下面更详细地解释)
  3. 当我们到达那一行时停止
  4. 打印行的 ID

该解决方案涉及for循环、if语句和正则表达式。

首先,这是我重现数据框的尝试。同样,细节并不重要。我只是想让“钱行”成为第二行,这在您的示例中似乎是这样的

   df<- data.frame(
   Assessment_Area = c(2,3,4,5),
   Offices = c("#",1,1,2),
   Dep_Percent_63016 = c("#","50.0%","50.0%","100.0%"),
   Dep_Total_63016 = c("$ (000s)", "$24,451", "$21,931","$46,382"),
   Assessment_Area_Rev = rep("Blah",4)
   )
   df

                  Assessment_Area Offices Dep_Percent_63016 Dep_Total_63016
          1               2       #                 #        $ (000s)
          2               3       1             50.0%         $24,451
          3               4       1             50.0%         $21,931
          4               5       2            100.0%         $46,382
                 Assessment_Area_Rev
          1                Blah
          2                Blah
          3                Blah
          4                Blah

这是for循环:

   library(stringr)
   for (i in 1:nrow(df)) {
   if (any(str_detect(df[i,],"^\\$\\d{1,3}(,\\d{3})*"))) {
   print(i)
   break
     }
    }

关键是if语句的行。如果逻辑向量的任何元素为真,则any返回。TRUE在这种情况下,向量是通过应用于stringr::str_detect索引为 的 df 的一行来创建的df[i,]str_detect返回一个逻辑向量 - 您提供一个字符向量和一个表达式以匹配该向量的元素。它返回TRUEFALSE为向量中的每个元素,在这种情况下是一行中的每个单元格。所以关键是正则表达式: "^\\$\\d{1,3}(,\\d{3})*"

这是我们在每一行中搜索的模式(货币单元格)。^\\$表示我们希望字符串以美元符号开头。两个反斜杠转义$字符,因为它是正则表达式中的元字符(结束锚点)。然后我们想要 1-3 位数字。这将匹配任何低于 1,000 美元的美元价值。然后我们指定表达式可以包含任意数字(包括 0),后跟三个数字。这将涵盖任何美元价值。

最后,如果我们遇到包含这些表达式之一的行,for循环将打印行号并结束循环,因此它将返回包含一个所需单元格的最低行号。在此示例中,输出为2。如果没有遇到适当的行,则不会发生任何事情。

获得这些信息后,您可能还想做更多事情,但如果您只需要包含货币表达式的最低行号,那么这就足够了。

仅查找美元符号、逗号和数字的不太优雅的正则表达式是:

     "[0-9$,]+"

这就是您所要求的,尽管我认为这不是您真正想要的,因为这将匹配类似的东西,56$,,$$78


推荐阅读