代码之家  ›  专栏  ›  技术社区  ›  Cyrus Mohammadian

如何识别R中行的镜像副本

r
  •  1
  • Cyrus Mohammadian  · 技术社区  · 7 年前

    在下面的so帖子中 How to identify partial duplicates of rows in R ,我问如何除去部分重复的行。我问的是:

    我想确定数据帧中行的“部分”匹配。具体地说,如果数据帧中的某一行在数据帧中的某个其他位置具有重复行(基于列子集之间的匹配),我希望创建一个值为1的新列。另外一个复杂性是数据框中的一列是数字列,如果绝对值匹配,我希望匹配。

    问题是,我需要确保当一行被标识为部分重复时,只有当匹配的列之一是镜像相对值,而不仅仅是绝对值的匹配时,才会这样。为了让事情更清楚,下面是上一篇文章的示例数据:

    name<-c("Richard Nixon", "Bill Clinton", "George Bush", "Richard Nixon")
    state<-c("California", "Indiana", "Florida", "California")
    num<-c("-258", "123", "42", "258")
    date<-c("day 2", "day 15", "day 3","day 45")
    (df<-as.data.frame(cbind(name,state,num, date)))
               name      state  num   date
    1 Richard Nixon California -258  day 2
    2  Bill Clinton    Indiana  123 day 15
    3   George Bush    Florida   42  day 3
    4 Richard Nixon California  258 day 45 
    

    以下是我上一篇文章的解决方案:

    df$absnum = abs(as.numeric(as.character(df$num)))
    df$newcol = duplicated(df[,c('name','state', 'absnum')]) | 
      duplicated(df[,c('name','state', 'absnum')], fromLast = T)
    
    #            name      state  num   date absnum newcol
    # 1 Richard Nixon California -258  day 2    258   TRUE
    # 2  Bill Clinton    Indiana  123 day 15    123  FALSE
    # 3   George Bush    Florida   42  day 3     42  FALSE
    # 4 Richard Nixon California  258 day 45    258   TRUE
    

    请注意,第1行和第4行都有标签 TRUE 在下面 newcol 很好。下面是新的示例数据,其中增加了复杂性问题:

    name<-c("Richard Nixon", "Bill Clinton", "George Bush", "Richard Nixon", "Bill 
    Clinton")
    state<-c("California", "Indiana", "Florida", "California", "Indiana")
    num<-c("-258", "123", "42", "258", "123")
    date<-c("day 2", "day 15", "day 3","day 45", "day 100")
    (df<-as.data.frame(cbind(name,state,num, date)))
    
      name           state      num   date
    1 Richard Nixon  California -258  day 2
    2 Bill Clinton   Indiana    123   day 15
    3 George Bush    Florida    42    day 3
    4 Richard Nixon  California 258   day 45
    5 Bill Clinton   Indiana    123   day 100
    

    注意,观察值2和5是部分重复的,但与1和4不同。我需要申请 真的 仅限于其绝对值与原始值匹配的观测值。因此,我希望结果返回以下内容:

      name           state      num   date    newcol
    1 Richard Nixon  California -258  day 2   TRUE
    2 Bill Clinton   Indiana    123   day 15  FALSE
    3 George Bush    Florida    42    day 3   FALSE
    4 Richard Nixon  California 258   day 45  TRUE
    5 Bill Clinton   Indiana    123   day 100 FALSE
    

    上一个So Post提供的解决方案将适用 真的 到第2行和第5行时,我只希望将此应用到第1行和第4行。

    2 回复  |  直到 7 年前
        1
  •  1
  •   akrun    7 年前

    一个选项是将“num”转换为 numeric 首先键入,创建另一列 abs olute值(“num1”),按“name”、“state”、“num1”分组, mutate 通过检查行数等于2来创建bool列( n() == 2 )和非重复的数目 sign “num”大于1

    library(tidyverse)
    df %>%
        mutate(num = as.numeric(num), num1 = abs(num)) %>% 
        group_by(name, state, num1) %>% 
        mutate(newcol = n() == 2 & n_distinct(sign(num)) > 1) %>%
        ungroup %>% 
        select(-num1)
    # A tibble: 5 x 5
    #  name          state        num date    newcol 
    #  <chr>         <chr>      <dbl> <chr>   <lgl>
    #1 Richard Nixon California  -258 day 2   TRUE 
    #2 Bill Clinton  Indiana      123 day 15  FALSE
    #3 George Bush   Florida       42 day 3   FALSE
    #4 Richard Nixon California   258 day 45  TRUE 
    #5 Bill Clinton  Indiana      123 day 100 FALSE
    

    注: cbind 创建一个 matrix 和 矩阵 只能有单个类型。因此,如果有任何字符列或元素,整个矩阵就变成 character 班级。把它包起来 data.frame ,传播并可以转换为 factor ( stringsAsFactors = TRUE -默认情况下)或 性格 (如果我们把它改成 FALSE )

    数据

    df <- data.frame(name, state, num, date, stringsAsFactors = FALSE)
    
        2
  •  2
  •   dww Jarretinha    7 年前

    在R基中,可以使用相同的 duplicated 在“部分”重复项上测试为链接问题,但排除相同的值

    df$numnum = as.numeric(as.character(df$num))
    df$absnum = abs(df$numnum)
    df$newcol = (duplicated(df[,c('name','state', 'absnum')]) | 
      duplicated(df[,c('name','state', 'absnum')], fromLast = T)) &
      !(duplicated(df$numnum) | duplicated(df$numnum, fromLast = T))
    #            name      state  num    date numnum absnum newcol
    # 1 Richard Nixon California -258   day 2   -258    258   TRUE
    # 2  Bill Clinton    Indiana  123  day 15    123    123  FALSE
    # 3   George Bush    Florida   42   day 3     42     42  FALSE
    # 4 Richard Nixon California  258  day 45    258    258   TRUE
    # 5  Bill Clinton    Indiana  123 day 100    123    123  FALSE