R 转换混合单位测量值

R 转换混合单位测量值,r,units-of-measurement,unit-conversion,R,Units Of Measurement,Unit Conversion,我有一个文件,包含大量非标准化的英制和公制混合测量值,我希望将其标准化并重新发布 该范围的示例如下所示: df <- data.frame(Measurements =c("1.25m", "2 Feet", "3 Inches", "5.5 cm")) |Measurements| |1.25m | |2 Feet | |3 Inches | |5.5 cm | |Measurements|MM_Conversion| |1.25m

我有一个文件,包含大量非标准化的英制和公制混合测量值,我希望将其标准化并重新发布

该范围的示例如下所示:

df  <- data.frame(Measurements =c("1.25m", "2 Feet", "3 Inches", "5.5 cm"))

|Measurements|
|1.25m       |
|2 Feet      |
|3 Inches    |
|5.5 cm      |
|Measurements|MM_Conversion|
|1.25m       |1200mm
|2 Feet      |609.6mm
|3 Inches    |76.2mm
|5.5 cm      |55mm
我不能使用measurements::conv\u unit或units::set\u unit,因为它们似乎都需要数字输入值。有没有一种简单的方法可以解析值和字符串,并进行相应的转换


编辑1:存在Conv_装置无法转换NA值的问题。如果初始向量为:df,则很容易实现,但必须首先在测量中确定单位,因为测量中可接受的长度单位::conv_unit

所以,英寸必须变成英寸,而脚应该变成英尺执行一些正则表达式的魔法;-。。但是

library(tidyverse)
df  <- data.frame( Measurements =c( "1.25m", "2 ft", "3 inch", "5.5 cm" ) )

df %>% 
  #extract the numeric and the unit-parts from the string
  mutate( num_part = as.numeric( stringr::str_extract( Measurements, "\\d+\\.*\\d*" ) ), 
          unit_part = stringr::str_extract( Measurements, "[a-zA-Z]+" ) ) %>%
  #perform a rowwise operation
  rowwise() %>% 
  #convert the units to mm, row-by-row
  mutate( in_mm = conv_unit( num_part, unit_part, "mm" ) )

# Source: local data frame [4 x 4]
# Groups: <by row>
#   # A tibble: 4 x 4
#   Measurements num_part unit_part  in_mm
#   <fct>           <dbl> <chr>      <dbl>
# 1 1.25m            1.25 m         1250  
# 2 2 ft             2    ft         610. 
# 3 3 inch           3    inch        76.2
# 4 5.5 cm           5.5  cm          55  

这很容易做到,但您必须首先确定测量中的单位,因为测量中可接受的长度单位::conv_unit

所以,英寸必须变成英寸,而脚应该变成英尺执行一些正则表达式的魔法;-。。但是

library(tidyverse)
df  <- data.frame( Measurements =c( "1.25m", "2 ft", "3 inch", "5.5 cm" ) )

df %>% 
  #extract the numeric and the unit-parts from the string
  mutate( num_part = as.numeric( stringr::str_extract( Measurements, "\\d+\\.*\\d*" ) ), 
          unit_part = stringr::str_extract( Measurements, "[a-zA-Z]+" ) ) %>%
  #perform a rowwise operation
  rowwise() %>% 
  #convert the units to mm, row-by-row
  mutate( in_mm = conv_unit( num_part, unit_part, "mm" ) )

# Source: local data frame [4 x 4]
# Groups: <by row>
#   # A tibble: 4 x 4
#   Measurements num_part unit_part  in_mm
#   <fct>           <dbl> <chr>      <dbl>
# 1 1.25m            1.25 m         1250  
# 2 2 ft             2    ft         610. 
# 3 3 inch           3    inch        76.2
# 4 5.5 cm           5.5  cm          55  
我们可以使用tidyr的提取物分离值和单位,并使用map2将其输入conv_单位:

结果:

请注意,我是如何手动缩写原始单位以使conv_单位工作的。如果原来的单位已经是缩写形式,那就少了一步

我们可以使用tidyr提取液分离数值和单位,并使用map2将其输入conv_单位:

结果:


请注意,我是如何手动缩写原始单位以使conv_单位工作的。如果原来的单位已经是缩写形式,那就少了一步

我能想到的一种方法是创建一个自定义函数,然后使用apply转换所有的度量值。我也这么想,但由于有20个不同的度量值,因此它变得很难使用。我能想到的一种方法是创建一个自定义函数,然后使用apply转换所有度量值。我也这么想,但由于有20种不同的测量方式,它变得很难使用。+1行方式使用得很好,但我尽量避免使用,因为它在dplyr意义上有点违反直觉。@avid_useR true,但因为conv_单元需要固定的单元,我想我应该在这一个方面走捷径-优雅的回答,从未用过吵闹。为了让我能理解发生了什么,你能解释一下“此处分组”到底是什么,以及“固定”单元是如何影响“conv_单元”功能的吗?注释掉它,并发现错误消息“无用”。@rsylian rowwise逐行执行操作。。。这是必要的,因为conv_unitx、from和to需要from是字符串,而不是向量。在@avid_useR的回答中,使用map解决了这个问题。在本例中,由于我设置了rowwise,所以每一行conv_unit都使用该特定行的参数x=num_part和from=unit_part。+1 rowwise使用得很好,但我尽量避免使用,因为它在dplyr意义上有点违反直觉。@avid_useR true,但因为conv_unit需要固定的单位,我想我会在这件事上抄近路-优雅的回答,从未用过吵闹。为了让我能理解发生了什么,你能解释一下“此处分组”到底是什么,以及“固定”单元是如何影响“conv_单元”功能的吗?注释掉它,并发现错误消息“无用”。@rsylian rowwise逐行执行操作。。。这是必要的,因为conv_unitx、from和to需要from是字符串,而不是向量。在@avid_useR的回答中,使用map解决了这个问题。在本例中,由于我按行设置,所以每一行conv_unit都使用该特定行的参数x=num_part和from=unit_part。回答也很优雅,但map2函数在这里做什么?conv_unit函数没有矢量化,因此,我们需要将每个元素的值和对应的单位映射到conv_单位。很抱歉我的运气有点不好,但举例来说,它是Measurements=cNA,1.25米,2英尺,3英寸,5.5厘米,答案就错了。找到一个非管道,但无法使其与您的答案一起工作。有没有什么方法可以合并not_na@rsylian谢谢你指出这一点。您希望任何NA行保持为NA,还是只是被删除?@rsylian查看我的更新。它现在应该与NA值一起工作。如果您想从输出中删除它们,还有另一个解决方案。答案也很好,但map2函数在这里做什么?conv_unit函数没有矢量化,因此我们需要将值的每个元素和相应的单位映射到conv_unit。抱歉让我有点走运,但例如,它是Measurements=cNA,1.25米,2英尺,3英寸,5.5厘米,答案是错的。找到一个非管道,但无法使其与您的答案一起工作。有没有什么方法可以合并not_na@rsylian谢谢你指出这一点。您希望任何NA行保持为NA,还是只是被删除?@rsylian查看我的更新。它现在应该与NA值一起工作。如果相反 如果要从输出中删除它们,还有另一个修复程序。
df <- data.frame(Measurements =c(NA, "1.25m", "2 Feet", "3 Inches", "5.5 cm"))

library(tidyverse)
library(stringr)
library(measurements)

df %>%
  extract(Measurements, c("value", "unit"), 
          regex = "^([\\d.]+)\\s*([[:alpha:]]+)$", 
          remove = FALSE, convert = TRUE) %>%
  mutate(unit = str_replace_all(unit, c(Feet="ft", Inches="inch")),
         MM_Conversion = paste0(map2(value, unit, ~if(!is.na(.x)) conv_unit(.x, .y, "mm") else NA), "mm"))
  Measurements value unit MM_Conversion
1         <NA>    NA <NA>          NAmm
2        1.25m  1.25    m        1250mm
3       2 Feet  2.00   ft       609.6mm
4     3 Inches  3.00 inch        76.2mm
5       5.5 cm  5.50   cm          55mm
df %>%
  extract(Measurements, c("value", "unit"), 
          regex = "^([\\d.]+)\\s*([[:alpha:]]+)$", 
          remove = FALSE, convert = TRUE) %>%
  filter(!is.na(Measurements)) %>%
  mutate(unit = str_replace_all(unit, c(Feet="ft", Inches="inch")),
         MM_Conversion = paste0(map2(value, unit, ~conv_unit(.x, .y, "mm")), "mm"))
  Measurements value unit MM_Conversion
1        1.25m  1.25    m        1250mm
2       2 Feet  2.00   ft       609.6mm
3     3 Inches  3.00 inch        76.2mm
4       5.5 cm  5.50   cm          55mm