【问题标题】:Changing numbers within string in R?在R中更改字符串中的数字?
【发布时间】:2013-11-05 19:03:34
【问题描述】:

我有一个问题,我希望有任何关于如何使用 R 的想法。问题是:我存储了一个乳胶表。表中数字均配备小数点后三位。我想把这些数字剪掉,把其他数字留在桌子上。 (想想代表估计结果的数字,但维度是“美元”。那么,145.553 的值没有多大意义,145 就足够了)。创建这些表格的人并没有考虑太多,所以我在这里尽量避免用手穿过表格。 :)

到目前为止,我只找到了如何从字符串中提取数字的不同解决方案,而不是如何更改它们以使字符串本身保持不变。

例子:

 strings <- c(
 "a.name      & $-436.735  $   & $-710.832$   \\\\", 
 "std(a.name) & $(1403.604)$   & $(1274.283)$ \\\\", 
 )

解决方案应该返回

 strings <- c(
 "a.name      & $-436  $   & $-710$   \\\\", 
 "std(a.name) & $(1403)$   & $(1274)$ \\\\", 
 )

当然,如果可以正确进行舍入,那就更好了。但这并不是最重要的。

我尝试使用gsub\\.... 来识别包含句点后跟三个其他数字的字符串,但这也给了我变量名称,在我的示例中为a.name

有没有人知道我如何才能完成我想做的事情?

提前致谢!

【问题讨论】:

    标签: regex string r gsub string-substitution


    【解决方案1】:

    这使用基数 R 的 gregexprregmatchesregmatches&lt;- 来舍入任何带小数部分的数字。

    即使对于像.789(即小数点前没有数字)和-0.4(应该四舍五入到没有减号的数字)这样的数字,它也能正常工作。它可能执行不理想的一种情况是它不会从像 10. 这样的数字中删除尾随小数。

    string <- c("a.name      & $-436.735  $   & $-710.832$   \\\\", 
                "std(a.name) & $(1403.604)$   & $(1274.283)$ \\\\")
    
    f <- function(x) {
        pat <- "(-)?[[:digit:]]+\\.[[:digit:]]*"
        m <- gregexpr(pat, x)
        regmatches(x,m) <- lapply(regmatches(x,m), function(X) round(as.numeric(X)))
        x
    }
    
    f(string)
    # [1] "a.name      & $-437  $   & $-711$   \\\\"
    # [2] "std(a.name) & $(1404)$   & $(1274)$ \\\\"
    

    【讨论】:

    • 非常感谢乔希。这是一个非常聪明的解决方案,我在这里学到了很多东西!
    • 很高兴有帮助。这个模板的好处是,一旦你提取了匹配项,你就可以使用lapply() 中的匿名函数(这里只是对数字进行四舍五入)来执行几乎任何你想要的操作。
    【解决方案2】:
    gsub(strings, pattern ="\\.[[:digit:]]{3}", replacement = "")
    #[1] "a.name      & $-436  $   & $-710$   \\\\" "std(a.name) & $(1403)$   & $(1274)$ \\\\"
    

    为了得到四舍五入,我会按照这些思路做一些事情,但是括号使它有点难看 -

    sapply(
      strsplit(
        strings,
        "\\$|\\$\\(|\\)\\$"
      ),
      function(x) 
        paste(
          x[1],'$',
          ifelse(as.numeric(x[2]) <0, round(as.numeric(x[2]),0),paste0("(",round(as.numeric(x[2]),0),")")),'$',
          x[3],'$',
          ifelse(as.numeric(x[4]) <0, round(as.numeric(x[4]),0),paste0("(",round(as.numeric(x[4]),0),")")),'$',
          x[5]
          )
    )
    #[1] "a.name      &  $ -437 $    &  $ -711 $    \\\\"   "std(a.name) &  $ (1404) $    &  $ (1274) $  \\\\"
    

    【讨论】:

    • 哇,这太棒了。我以前从未见过[[:digit:]]{3} 部分。我不太确定它是如何工作的,但确实如此。非常感谢 Codoremifa!
    • 顺便说一句,我很乐意获得任何关于好的资源的提示,我可以在其中了解更多关于正则表达式的信息。如果您知道,请随时分享。
    • 老实说,我自己正在通过在 SO 上移动来学习正则表达式。我也在尝试四舍五入等,但这似乎有点复杂。见编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    相关资源
    最近更新 更多