【问题标题】:Round numeric values in comma-separated string column在逗号分隔的字符串列中舍入数值
【发布时间】:2022-01-17 00:37:03
【问题描述】:

我想对逗号分隔的字符串列中的值进行舍入:

df <- structure(list(id = 1:8,
                     value = c("0.0081007", NA, NA,"0.00699123", 
                               "0.175555, 0.106897, 0.0289, 0.255005", 
                               NA, NA, "0.0047777, 0.8970001")), 
                class = c("tbl_df", "tbl", "data.frame"), 
                row.names = c(NA, -8L))

我可以如下图所示,但怀疑这是最简洁/最有效的方式:

library(dplyr)
df %>%
  mutate(value = lapply(str_extract_all(value, "[\\d.]+"), function(x) round(as.numeric(x), 3))) %>%
  unnest(value) %>%
  group_by(id) %>%
  summarise(
    value = toString(value))
# A tibble: 8 × 2
     id value                     
  <int> <chr>                     
1     1 0.008                     
2     2 NA                        
3     3 NA                        
4     4 0.007                     
5     5 0.176, 0.107, 0.029, 0.255
6     6 NA                        
7     7 NA                        
8     8 0.005, 0.897 

有没有更短/更简洁的dplyr 方式?

【问题讨论】:

  • 您也可以在单个 mutate 行中使用此问题的最佳答案,但这确实需要另一个库,并且对于某些人来说可能不太直观地看到发生了什么。 stackoverflow.com/questions/38204034/…

标签: r dplyr


【解决方案1】:

您可以使用separate_rows() 使其更简洁。

library(dplyr)
library(tidyr)

df %>% 
  separate_rows(value, sep = ",", convert = TRUE) %>% 
  group_by(id) %>%
  summarise(value = toString(round(value, 3)))

【讨论】:

    【解决方案2】:

    听着,妈妈,不tidyverse

    df$value <- sapply(
        sprintf('round(c(%s), 3)', df$value), 
        \(x) { toString(eval(str2expression(x)))  }
    )
    
    df
    
    # # A tibble: 8 x 2
    #      id value                     
    #   <int> <chr>                     
    # 1     1 0.008                     
    # 2     2 NA                        
    # 3     3 NA                        
    # 4     4 0.007                     
    # 5     5 0.176, 0.107, 0.029, 0.255
    # 6     6 NA                        
    # 7     7 NA                        
    # 8     8 0.005, 0.897   
    

    【讨论】:

    • 或者重新整理...df %&gt;% mutate(value = map_chr(sprintf("round(c(%s), 3)", value), ~ toString(eval(str2expression(.x)))))(我忍不住!)。很好的答案。
    • @Adam 一直在考虑 :) 基管 |&gt; 短了一个符号
    • 啊,妈妈,说到非 tidyverse:df$value &lt;- sapply(strsplit(df$value, ", "), function(x) round(as.numeric(x), 3)) 可以在 df &lt;- data.frame(id = 1:8, value = c("0.0081007", NA, NA,"0.00699123", "0.175555, 0.106897, 0.0289, 0.255005", NA, NA, "0.0047777, 0.8970001")) 这样的数据帧上完美运行,而且对我来说看起来更整洁,妈妈!
    • 哦,我一直认为简单、简洁或严谨是编码的价值......
    • @ChrisRuehlemann 抱歉,我没有加入会众。我同意您的解决方案更适合这种情况。但是,它在概念上与answer given by Adam. 相同,这正是我拒绝发布此解决方案的原因。对于您的特定情况,它可能不是很有用,但对于我以及正在学习使用表达式、替换、函数工厂等的人来说,这可能是一个很好的起点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    相关资源
    最近更新 更多