Dataframe中的数据屏蔽

时间:2017-12-19 09:24:10

标签: r dataframe data-masking

  • 我有一个包含8个唯一值的数据框

     data<-data.frame(id=c("ab","cc","cc","dd","ee","ff","ee","ff","ab","dd","gg",1,"air"))
     >data
           id
        1  ab
        2  cc
        3  cc
        4  dd
        5  ee
        6  ff
        7  ee
        8  ff
        9  ab
        10 dd
        11 gg
        12 1
        13 air 
    
  • 我创建了另一个包含8个唯一值的数据框,这些值将用作替换

     library(random)
     replacements<-data.frame(value=randomStrings(n=8, len=2, digits=FALSE,loweralpha=TRUE, unique=TRUE, check=TRUE))
     replacements 
      V1
     1 SJ
     2 fH
     3 TZ
     4 Mr
     5 oZ
     6 kZ
     7 fe
     8 ql
    
  • 我想将data dataframe中的所有唯一值替换为replacement dataframe中的值

所有ab值均由SJ替换 所有cc值均由fH替换 所有dd值均由TZ替换 所有的ee价值都由何先生取代 所有ff值均由oZ替换 所有gg值均由kZ替换 所有1个值都替换为fe
所有空气值均由ql

取代
  • 目前,我通过以下方式实现这一目标:

        data<-data.frame(id=c("ab","cc","cc","dd","ee","ff","ee","ff","ab","dd","gg",1,"air"))
        data$id<-as.character(data$id)
        replacements<-data.frame(value=randomStrings(n=8, len=2, digits=FALSE,loweralpha=TRUE, unique=TRUE, check=TRUE))
        replacements$V1<-as.character(replacements$V1)
        for(i in 1:length(unique(data$id))){
             data$id[data$id %in% data$id[i]] <- replacements$V1[i]
        }  
    
    
        >data
           id
        1  SJ
        2  fH
        3  fH
        4  TZ
        5  Mr
        6  oZ
        7  Mr
        8  oZ
        9  SJ
        10 TZ
        11 kZ
        12 fe
        13 ql
    
  • R中是否有任何基本功能可以实现?是否更好的方法比屏蔽数据更好?

2 个答案:

答案 0 :(得分:1)

我建议您使用merge(),但为了做到这一点,您首先需要向data$id添加一列唯一的replacements,因为两个data.frame都需要有一个列常见的。

此处data

> data
    id
1   ab
2   cc
3   cc
4   dd
5   ee
6   ff
7   ee
8   ff
9   ab
10  dd
11  gg
12   1
13 air

此处replacements

> replacements
  V1
1 VS
2 Of
3 bH
4 iJ
5 jm
6 kH
7 cm
8 rQ

因此,请将data$id添加到replacements

replacements$id <- unique(data$id)

,并提供:

  V1  id
1 VS  ab
2 Of  cc
3 bH  dd
4 iJ  ee
5 jm  ff
6 kH  gg
7 cm   1
8 rQ air

然后使用datareplacementsid合并:

data <- merge(data, replacements, by = "id", all.x = TRUE, sort = FALSE)

,并提供:

    id V1
1   ab VS
2   ab VS
3   cc Of
4   cc Of
5   dd bH
6   dd bH
7   ee iJ
8   ee iJ
9   ff jm
10  ff jm
11  gg kH
12   1 cm
13 air rQ

如果您真的只想保留新的id列,则可以删除原始id并重命名新列:

data <- data[, 2, drop = FALSE]
colnames(data) <- "id"

,并提供:

   id
1  VS
2  VS
3  Of
4  Of
5  bH
6  bH
7  iJ
8  iJ
9  jm
10 jm
11 kH
12 cm
13 rQ

答案 1 :(得分:1)

  • 使用算法CRC32

    屏蔽数据
    library(data.table)
    library(digest)
    data<-data.frame(id=c("ab","cc","cc","dd","ee","ff","ee","ff","ab","dd","gg",1,"air"))
    setDT(data)
    
    anonymize <- function(x, algo="crc32"){
        unq_hashes <- vapply(unique(x), function(object) digest(object, algo=algo), FUN.VALUE="", USE.NAMES=TRUE)
        unname(unq_hashes[x])
    }
    
    cols_to_mask <- c("id")
    data[,cols_to_mask := lapply(.SD, anonymize),.SDcols=cols_to_mask,with=FALSE]
    

参考文献:Data anonymization in R