问题描述
我正在尝试确定第一行,其中的一个数据单元格在数据帧中仅包含数字“,”,“ $”:
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
我只想知道这一行。
解决方法
您的数据可能需要一些清理,但并不是完全有必要解决您的问题。您想找到包含美元符号和适当值的第一行。我的解决方案执行以下操作:
- 遍历行
- 在每一行中,询问是否至少有一个以美元符号开头的单元格,然后是数字和逗号的特定组合(将在下面进行详细说明)
- 到达该行时停止
- 打印行的ID
该解决方案涉及一个for
循环,一个if
语句和一个正则表达式。
首先,这是我尝试重现数据帧的尝试。同样,细节并不重要。我只是想将“金钱行”设置为第二行,这与您的示例中的显示方式类似
df<- data.frame(
Assessment_Area = c(2,3,4,5),Offices = c("#",1,2),Dep_Percent_63016 = c("#","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
语句的行。如果逻辑向量的任何元素为true,则any
返回TRUE
。在这种情况下,矢量是通过将stringr::str_detect
应用于索引为df[i,]
的df行来创建的。 str_detect
返回一个逻辑向量-您提供一个字符向量和一个表达式以匹配该向量的元素。它为向量中的每个元素返回TRUE
或FALSE
,在这种情况下,向量是一行中的每个单元格。因此,关键在于正则表达式:
"^\\$\\d{1,\\d{3})*"
这是我们在每一行中搜索的模式(货币单元)。 ^\\$
表示我们希望字符串以美元符号开头。两个反斜杠转义了$
字符,因为它是正则表达式中的元字符(结尾锚)。然后,我们需要1-3位数字。这将匹配任何低于$ 1,000的美元价值。然后,我们指定表达式可以包含,
的任何数字(包括0),后跟另外三个数字。这将涵盖任何美元价值。
最后,如果遇到包含这些表达式之一的行,则for
循环将打印该行的编号并结束循环,因此它将返回包含一个所需单元格的最低行号。在此示例中,输出为2
。如果没有遇到适当的行,将不会发生任何事情。
掌握了这些信息后,您可能还会想做更多的事情,但是如果您所需要的只是包含您的货币表达方式的最低行号,那么这就足够了。
一个不太优雅的正则表达式,仅查找美元符号,逗号和数字将是:
"[0-9$,]+"
这是您所要的,尽管我认为这不是您真正想要的,因为它可以匹配,56$,$$78