Search code examples
rdplyrpurrr

How to mutate a column with different tempfiles?


I'd like to mutate a column with different tempfiles. How can I do it, given that tempfile() isn't vectorized? The following code simply returns the same tempfile.

library(dplyr)

df <- tibble(foo = 1:5)
df |> 
  mutate(my_tmp_file = tempfile())
#> # A tibble: 5 × 2
#>     foo my_tmp_file                                                             
#>   <int> <chr>                                                                   
#> 1     1 /var/folders/6g/tmb5z48550s3dl4dp56dvy780000gp/T//RtmpHag8uI/file5cb067… 
#> 2     2 /var/folders/6g/tmb5z48550s3dl4dp56dvy780000gp/T//RtmpHag8uI/file5cb067…  
#> 3     3 /var/folders/6g/tmb5z48550s3dl4dp56dvy780000gp/T//RtmpHag8uI/file5cb067… 
#> 4     4 /var/folders/6g/tmb5z48550s3dl4dp56dvy780000gp/T//RtmpHag8uI/file5cb067…
#> 5     5 /var/folders/6g/tmb5z48550s3dl4dp56dvy780000gp/T//RtmpHag8uI/file5cb067…

I thought I could mutate with purrr::map(), supplying tempfile() as the function, but map() requires also .x which I don't have/need, so I get an error of argument ".x" is missing, with no default.

What else can I do?


Solution

  • You can use replicate:

    df |>
      mutate(tf = replicate(n(), tempfile()))
    # # A tibble: 5 × 2
    #     foo tf                                                                 
    #   <int> <chr>                                                              
    # 1     1 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2818ba128f"
    # 2     2 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2849741e4" 
    # 3     3 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2816206e5c"
    # 4     4 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2831543f8c"
    # 5     5 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2813456146"
    

    Or if foo is guaranteed-unique, you can use foo as part of the name,

    df |>
      mutate(tf = paste0(tempfile(), "_", foo))
    # # A tibble: 5 × 2
    #     foo tf                                                                 
    #   <int> <chr>                                                              
    # 1     1 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2834c2b5_1"
    # 2     2 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2834c2b5_2"
    # 3     3 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2834c2b5_3"
    # 4     4 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2834c2b5_4"
    # 5     5 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2834c2b5_5"
    

    If you really want/need to use purrr, then tempfile() can still be used, we'll ignore the .x:

    df |>
      mutate(tf = purrr::map_chr(foo, ~ tempfile()))
    # # A tibble: 5 × 2
    #     foo tf                                                                 
    #   <int> <chr>                                                              
    # 1     1 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a28487ffb9" 
    # 2     2 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2839cf352e"
    # 3     3 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a286e5c5cce"
    # 4     4 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a2825b6280" 
    # 5     5 "C:\\Users\\r2\\AppData\\Local\\Temp\\Rtmp2REMs5\\file3a286a1f9e6"