【问题标题】:Transforming complete age from character to numeric in R在R中将完整年龄从字符转换为数字
【发布时间】:2022-01-08 10:52:36
【问题描述】:

我有一个数据集,其中人们的完整年龄为 R 中的字符串(例如,“10 年 8 个月 23 天),我需要将其转换为有意义的数字变量。我正在考虑将其转换为这个人有很多天(这很难,因为几个月有不同的天数)。所以最好的解决方案可能是创建一个双变量,将年龄显示为 10.6 或 10.8,一些数字变量包含 10 年 8 个月 5 天的信息大于 10 年 7 个月 12 天。

这是我当前变量的示例

library(tibble)

age <- tibble(complete_age = 
             c("10 years 8 months 23 days",
               "9 years 11 months 7 days",
               "11 years 3 months 1 day",
               "8 years 6 months 12 days")) 

age

# A tibble: 4 x 1
  complete_age             
  <chr>                    
1 10 years 8 months 23 days
2 9 years 11 months 7 days 
3 11 years 3 months 1 day  
4 8 years 6 months 12 days 

这是我希望看到的可能结果的示例(age_num 的近似值)

> age
# A tibble: 4 x 2
  complete_age              age_num
  <chr>                       <dbl>
1 10 years 8 months 23 days    10.66
2 9 years 11 months 7 days      9.92
3 11 years 3 months 1 day      11.27
4 8 years 6 months 12 days      8.52

总之,我有一个包含“complete_age”列的数据集,我想创建列“age_num”。

如何在 R 中做到这一点?我很难尝试使用 stringrlubridate 但也许这是要走的路?

【问题讨论】:

    标签: r data-cleaning lubridate stringr data-wrangling


    【解决方案1】:

    使用lubridate 便利函数,periodtime_length

    library(lubridate)
    age %>% 
      mutate(age_years = time_length(period(complete_age), unit = "years"))
    
      # A tibble: 4 x 2
      #  complete_age              age_years
      # <chr>                         <dbl>
      # 1 10 years 8 months 23 days 10.729637
      # 2  9 years 11 months 7 days  9.935832
      # 3   11 years 3 months 1 day 11.252738
      # 4  8 years 6 months 12 days  8.532854
    

    【讨论】:

    • 我知道我可以为此使用lubridate...这正是我想要的。谢谢
    【解决方案2】:

    空间分割,然后计算。请注意,您可能希望根据需要更改一年、一个月的平均天数:

    age %>% 
      separate(complete_age, into = c("Y", NA, "M", NA, "D", NA), 
               convert = TRUE, remove = FALSE) %>% 
      transmute(complete_age, age_num = Y + (M * 30.45 + D) / 365.25)
    
    # # A tibble: 4 x 2
    #   complete_age                 age_num
    #   <chr>                          <dbl>
    # 1 10 years 8 months 23 days      10.7 
    # 2 9 years 11 months 7 days        9.94
    # 3 11 years 3 months 1 day        11.3 
    # 4 8 years 6 months 12 days        8.53
    

    【讨论】:

      【解决方案3】:

      这是另一种方法:

      1. 删除所有字母 '[A-Za-z]'str_remove_all
      2. 将结果数字分开
      3. 使用type.convert(as.is = TRUE) 切换到数字后应用计算
      4. bind_cols重新绑定到原来的cols
      library(dplyr)
      library(stringr)
      age %>% 
        mutate(complete_age = str_remove_all(complete_age, "[A-Za-z]")) %>% 
        separate(complete_age, c("year", "month", "day")) %>% 
        type.convert(as.is = TRUE) %>% 
        mutate(ageYear = (year + month/12 + day/365), .keep="unused") %>% 
        bind_cols(age)
      
        ageYear complete_age             
          <dbl> <chr>                    
      1   10.7  10 years 8 months 23 days
      2    9.94 9 years 11 months 7 days 
      3   11.3  11 years 3 months 1 day  
      4    8.53 8 years 6 months 12 days 
      

      【讨论】:

      • 我非常喜欢你方法的最后一部分!
      猜你喜欢
      • 1970-01-01
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多