【问题标题】:R - How to pass parameters to function in "mutate across"?R - 如何将参数传递给“跨越”函数?
【发布时间】:2021-04-16 10:24:48
【问题描述】:

我有一个数据框,其中包含多个日期值作为字符串的列(格式:YYYYMMDD)。

dt_example <- data.frame ( 
    W03 = "20201130",
    W44 = "19711031",
    P01 = "19740813",
    P04 = "20000506",
    Z02 = "20201231"
  )

现在我想将字符串转换为日期格式,并尝试了以下代码,效果很好:

dt_example_date <- dt_example %>% 
  mutate(
    W03 = as.Date(W03, "%Y%m%d")
    ,W44 = as.Date(W44, "%Y%m%d")
    ,P01 = as.Date(P01, "%Y%m%d")
    ,P04 = as.Date(P04, "%Y%m%d")
    ,Z02 = as.Date(Z02, "%Y%m%d")
  )

但是这段代码很烦人,我想使用“mutate across”而不是 mutliple as.Date-conversions。

我尝试了几种替代方法,但没有任何效果。

dt_example_date_2 <- dt_example %>% 
  mutate(
    across(
      c("W03","W44","P01","P04","Z02")
      ,as.Date
    )
  )

结果:字符串不是标准的明确格式

dt_example_date_2 <- dt_example %>% 
  mutate(
    across(
      c("W03","W44","P01","P04","Z02")
      ,as.Date(format="%y%m%d")
    )
  )

结果:缺少参数“x”

dt_example_date_2 <- dt_example %>% 
  mutate(
    across(
      c("W03","W44","P01","P04","Z02")
      ,as.Date(., format="%y%m%d")
    )
  )

结果:不知道如何转换'.'上课“日期”

我没听懂也不知道该怎么办。

如何将参数传递给交叉命令中使用的函数?

问候 本内

【问题讨论】:

    标签: r string date dplyr across


    【解决方案1】:

    你可以使用 lubridate 包:

    data.frame ( 
      W03 = "20201130",
      W44 = "19711031",
      P01 = "19740813",
      P04 = "20000506",
      Z02 = "20201231"
    ) %>% 
      mutate(across(everything(), lubridate::ymd))
    
    

    这给出了:

             W03        W44        P01        P04        Z02
    1 2020-11-30 1971-10-31 1974-08-13 2000-05-06 2020-12-31
    
    

    【讨论】:

      【解决方案2】:

      Base R 解决方案:如果之前将结构转换为矩阵,则可以简单地将结构直接传递给 as.Date。

      dt_example_date <- as.Date(as.matrix(dt_example), "%Y%m%d")
      # [1] "2020-11-30" "1971-10-31" "1974-08-13" "2000-05-06" "2020-12-31"
      
      str(dt_example_date)
      #  Date[1:5], format: "2020-11-30" "1971-10-31" "1974-08-13" "2000-05-06" "2020-12-31"
      

      或保留数据帧结构:

      as.data.frame(sapply(X = dt_example, FUN = as.Date, "%Y%m%d", simplify = F))
      #         W03        W44        P01        P04        Z02
      #1 2020-11-30 1971-10-31 1974-08-13 2000-05-06 2020-12-31
      

      【讨论】:

        【解决方案3】:

        您可以尝试acrosseverything(),如下所示

        > dt_example %>%
        +   mutate(across(everything(), as.Date, format = "%Y%m%d"))
                 W03        W44        P01        P04        Z02
        1 2020-11-30 1971-10-31 1974-08-13 2000-05-06 2020-12-31
        

        data.table 选项是

        > setDT(dt_example)[, lapply(.SD, as.Date, format = "%Y%m%d")]
                  W03        W44        P01        P04        Z02
        1: 2020-11-30 1971-10-31 1974-08-13 2000-05-06 2020-12-31
        

        使用list2DF + Map 的基本 R 选项

        > list2DF(Map(as.Date, dt_example, "%Y%m%d"))
                 W03        W44        P01        P04        Z02
        1 2020-11-30 1971-10-31 1974-08-13 2000-05-06 2020-12-31
        

        【讨论】:

          【解决方案4】:

          试试这个:

          #Code
          dt_example_date_2 <- dt_example %>% 
            mutate(
              across(
                c(W03,W44,P01,P04,Z02)
                ,~as.Date(.,format="%Y%m%d")
              )
            )
          

          输出:

          dt_example_date_2
                   W03        W44        P01        P04        Z02
          1 2020-11-30 1971-10-31 1974-08-13 2000-05-06 2020-12-31
          

          为了避免输入所有名字,您可以试试这个(非常感谢@latlio):

          #Code 2
          dt_example_date_2 <- dt_example %>% 
            mutate(
              across(
                everything()
                ,~as.Date(.,format="%Y%m%d")
              )
            )
          

          相同的输出。

          【讨论】:

          • 在这种情况下,您也可以指定everything(),而不是输入所有列名!
          • @latlio 你是完全正确的,我会把它添加到帖子中,感谢你!非常感谢!
          • 感谢大家。第一个解决方案最合适。
          【解决方案5】:

          a) 您需要以逗号分隔传递格式参数。
          b) 你的格式有错字(小写“y”而不是大写)。

          dt_example %>%
            mutate(across(c("W03","W44","P01","P04","Z02"), as.Date, format = "%Y%m%d"))
          

          给予:

                   W03        W44        P01        P04        Z02
          1 2020-11-30 1971-10-31 1974-08-13 2000-05-06 2020-12-31
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-07
            • 2015-10-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多