为类似名称的一个id分配一个名称

时间:2017-08-04 10:00:08

标签: r dataframe

我有100万观察值和4个变量(ID,NAME,COMPANY,TIPS) 我的ID值已正确映射,但在NAME列中包含全名,有些只有名字,但每个id(2,3,4)的末尾只有一个全名,所以我想将全名替换为所有id这样我就可以显示一个id和一个正确的名字 样本数据表如下(Dt - 格式)

ID   Name                      Company   Tips   
1    Dave                       AB       50
2    PAT E DAV                  ABC      15
2    PAT ERIN DAV(full name)    AB       26  
3    JIL WIRTH                  DFG      26
3    JIL K WIRTH                EF       45
3    JILL KATH WIRTH(full name) JUI      85
4    MARIANA PO                 KIL      50
4    MARIANA A PO(full name)    LPI      55
5    BRET                       LLC      52

预期产出

   ID   Name                   Company   Tips   
    1    Dave                  AB       50
    2    PAT ERIN DAV          ABC      15
    2    PAT ERIN DAV          AB       26  
    3    JIL KATH WIRTH        DFG      26
    3    JIL KATH WIRTH        EF       45
    3    JILL KATH WIRTH       JUI      85
    4    MARIANA A PO          KIL      50
    4    MARIANA A PO          LPI      55
    5    BRET                  LLC      52

3 个答案:

答案 0 :(得分:2)

一种方法是为每个ID取最长的名称。以下是使用dplyr ...

的方法
library(dplyr)
df <- df %>% group_by(ID) %>% mutate(Name2=Name[which.max(nchar(Name))])

df
     ID            Name Company  Tips           Name2
  <int>           <chr>   <chr> <int>           <chr>
1     1            Dave      AB    50            Dave
2     2       PAT E DAV     ABC    15    PAT ERIN DAV
3     2    PAT ERIN DAV      AB    26    PAT ERIN DAV
4     3       JIL WIRTH     DFG    26 JILL KATH WIRTH
5     3     JIL K WIRTH      EF    45 JILL KATH WIRTH
6     3 JILL KATH WIRTH     JUI    85 JILL KATH WIRTH
7     4      MARIANA PO     KIL    50    MARIANA A PO
8     4    MARIANA A PO     LPI    55    MARIANA A PO
9     5            BRET     LLC    52            BRET

要使用新值覆盖Name,只需将Name2更改为Name

答案 1 :(得分:2)

基础R解决方案将基于full name进行排序并替换。最后一步是移除gsub

(full name)
gsub('\\(.*', '', with(df[order(df$ID, 
                 gsub("[\\(\\)]", "", regmatches(df$Name, gregexpr("\\(.*?\\)", 
                     df$Name)))),], ave(Name, ID, FUN = function(i) `<-`(i, tail(i, 1)))))

#[1] "Dave" "PAT ERIN DAV" "PAT ERIN DAV" "JILL KATH WIRTH" "JILL KATH WIRTH" "JILL KATH WIRTH" "MARIANA A PO" "MARIANA A PO"   
#[9] "BRET"

答案 2 :(得分:0)

解决方案使用dplyrtidyr中的函数。它使用每个ID的最后一个填充Namedt2是最终输出。

如果(full name)确实在您的数据框中,并且您想删除它,那么我们可以使用gsub和正则表达式来执行此操作。 dt3是最终输出。

# Load packages
library(dplyr)
library(tidyr)

# Create example data frames
dt <- read.table(text = "ID   Name                      Company   Tips   
1    Dave                       AB       50
                 2    'PAT E DAV'                  ABC      15
                 2    'PAT ERIN DAV(full name)'    AB       26  
                 3    'JIL WIRTH'                  DFG      26
                 3    'JIL K WIRTH'                EF       45
                 3    'JILL KATH WIRTH(full name)' JUI      85
                 4    'MARIANA PO'                 KIL      50
                 4    'MARIANA A PO(full name)'    LPI      55
                 5    'BRET'                       LLC      52",
                 header = TRUE, stringsAsFactors = FALSE)


dt2 <- dt %>%
  group_by(ID) %>%
  # Replace names that are not on the last row of each ID to be NA
  mutate(Name = ifelse(row_number() != n(), NA, Name)) %>%
  # Fill NA with the name from the last row
  fill(Name, .direction = "up")

# Remove the string (full name)
dt3 <- dt2 %>% mutate(Name = gsub("\\s*\\([^\\)]+\\)", "", Name))