【问题标题】:R - map vector of unique values to dataframe column with duplicatesR - 将唯一值的向量映射到具有重复项的数据框列
【发布时间】:2022-01-09 20:28:17
【问题描述】:

我在数据框中有一列是字符向量。我想在我的数据框中添加一列,其中包含与所述列中每个唯一值相对应的唯一 ID 值/代码。这是一些玩具数据:

fnames <- c("joey", "joey", "joey", "jimmy", "jimmy", "tommy", "michael", "michael", "michael", "michael", "michael", "kevin", "kevin", "christopher", "aaron", "joshua", "joshua", "joshua", "arvid", "aiden", "kentavious", "lawrence", "xavier")

names <- as.data.frame(fnames)

要获取 fnames 的唯一值的数量,我运行:

unique_fnames <- length(unique(names$fnames))

要为每个唯一名称生成唯一 ID,我找到了以下函数:

create_unique_ids <- function(n, seed_no = 16169, char_len = 6){
  set.seed(seed_no)
  pool <- c(letters, LETTERS, 0:9)
  
  res <- character(n)
  for(i in seq(n)){
    this_res <- paste0(sample(pool, char_len, replace = TRUE), collapse = "")
    while(this_res %in% res){
      this_res <- paste0(sample(pool, char_len, replace = TRUE), collapse = "")
    }
    res[i] <- this_res
  }
  res
}

create_unique_ids 应用到unique_fnames 我得到所需数量的ID 代码:

unique_fname_id <- create_unique_ids(unique_fnames)

我的问题是这样的:

如何将unique_fname_id 的向量添加到我的数据框names?期望的结果是一个数据框names,其中有一个unique_fname_id 列,看起来像这样:

unique_fname_id &lt;- c("VvWMKt", "VvWMKt", "VvWMKt", "yEbpFq", "yEbpFq", "Z3xCdO"...)

其中"VvWMKt"对应"joey""yEbpFq"对应"jimmy"等等。数据框 names 将与原始数据框长度相同,只是添加了这一列。

有没有办法做到这一点?欢迎和赞赏所有建议。谢谢!

编辑:我需要在create_unique_ids函数中保留set.seed,以确保生成的ID可以连续复制。

【问题讨论】:

    标签: r dataframe random unique


    【解决方案1】:

    如果你想使用你的函数并保留种子,你可以这样做:

    names %>% 
      distinct(fnames) %>% 
      bind_cols(unique_ID = create_unique_ids(13)) %>% 
      left_join(names)
    

    您还可以从您的函数中删除种子(set.seed(seed_no) 行和参数)并获得更简单的解决方案:

    names %>% 
      group_by(fnames) %>% 
      mutate(unique_ID = create_unique_ids(1))
    
       fnames  unique_ID
       <chr>   <chr>    
     1 joey    ea10KC   
     2 joey    ea10KC   
     3 joey    ea10KC   
     4 jimmy   MD5W4d   
     5 jimmy   MD5W4d   
     6 tommy   xR7ozW   
     7 michael uuGn3h   
     8 michael uuGn3h   
     9 michael uuGn3h   
    10 michael uuGn3h   
    # ... with 13 more rows
    

    您还可以使用像stringi::stri_rand_strings 这样的内置函数,它创建具有固定字符数的随机字母数字字符串:

    library(stringi); library(dplyr)
    
    names %>% 
      group_by(fnames) %>% 
      mutate(unique_ID = stri_rand_strings(1, 6))
    

    【讨论】:

    • 这可行,但我需要保留set.seed 以保持可重复性。我将编辑我的问题以反映这一点。
    • 好的,我编辑了我的答案。
    【解决方案2】:

    一个粗略的方法是左加入它回来

    library(tidyverse)
    
    fnames <- c("joey", "joey", "joey", "jimmy", "jimmy", "tommy", "michael", "michael", "michael", "michael", "michael", "kevin", "kevin", "christopher", "aaron", "joshua", "joshua", "joshua", "arvid", "aiden", "kentavious", "lawrence", "xavier")
    
    names <- as.data.frame(fnames)
    
    
    unique_names <- names |> distinct()
    
    unique_fnames <- length(unique(names$fnames))
    
    create_unique_ids <- function(n, seed_no = 16169, char_len = 6){
      set.seed(seed_no)
      pool <- c(letters, LETTERS, 0:9)
      
      res <- character(n)
      for(i in seq(n)){
        this_res <- paste0(sample(pool, char_len, replace = TRUE), collapse = "")
        while(this_res %in% res){
          this_res <- paste0(sample(pool, char_len, replace = TRUE), collapse = "")
        }
        res[i] <- this_res
      }
      res
    }
    
    unique_fname_id <- create_unique_ids(unique_fnames)
    
    
    df_ids <- tibble(fnames = unique_names |> pull(fnames),unique_fname_id = unique_fname_id)
    
    
    names |> 
      left_join(df_ids)
    #> Joining, by = "fnames"
    #>         fnames unique_fname_id
    #> 1         joey          VvWMKt
    #> 2         joey          VvWMKt
    #> 3         joey          VvWMKt
    #> 4        jimmy          yEbpFq
    #> 5        jimmy          yEbpFq
    #> 6        tommy          Z3xCdO
    #> 7      michael          ef8YkZ
    #> 8      michael          ef8YkZ
    #> 9      michael          ef8YkZ
    #> 10     michael          ef8YkZ
    #> 11     michael          ef8YkZ
    #> 12       kevin          kDBFAq
    #> 13       kevin          kDBFAq
    #> 14 christopher          xR77mJ
    #> 15       aaron          gaaI1C
    #> 16      joshua          KM4dD9
    #> 17      joshua          KM4dD9
    #> 18      joshua          KM4dD9
    #> 19       arvid          oTLl7g
    #> 20       aiden          b63PnV
    #> 21  kentavious          csnWuE
    #> 22    lawrence          Ihi5VM
    #> 23      xavier          HfM0mX
    

    reprex package (v2.0.1) 于 2021-12-03 创建

    【讨论】:

    • 这似乎有效,但我对|&gt; 感到困惑。你能解释一下吗?
    • 它是 r 的新管道,它不会完全取代 magritrr 管道,如果您不知道管道的想法而不是 f(a,b) == a |&gt; f(b)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2018-02-08
    • 2020-08-26
    • 2020-08-25
    • 2020-10-04
    • 2020-11-13
    相关资源
    最近更新 更多