Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux R中变量的模糊匹配合并_Linux_R_Unix - Fatal编程技术网

Linux R中变量的模糊匹配合并

Linux R中变量的模糊匹配合并,linux,r,unix,Linux,R,Unix,我有两个数据帧(x&y),其中id是学生名,父亲名和母亲名。由于印刷错误(“n”而不是“m”、随机空格等),我有大约60%的值没有对齐,尽管我可以仔细查看数据并发现它们应该对齐。有没有一种方法可以减少不匹配的程度,这样手动编辑至少是可行的?数据帧具有大约700K的观测值 R最好。我懂一点python和一些基本的unix工具。另外,我阅读了agrep(),但不明白这在实际数据集上如何起作用,特别是当匹配超过一个变量时 更新(公布的赏金数据): 是两个示例数据帧,站点a和站点b。它们可以在数值列l

我有两个数据帧(x&y),其中id是
学生名
父亲名
母亲名
。由于印刷错误(“n”而不是“m”、随机空格等),我有大约60%的值没有对齐,尽管我可以仔细查看数据并发现它们应该对齐。有没有一种方法可以减少不匹配的程度,这样手动编辑至少是可行的?数据帧具有大约700K的观测值

R最好。我懂一点python和一些基本的unix工具。另外,我阅读了agrep(),但不明白这在实际数据集上如何起作用,特别是当匹配超过一个变量时


更新(公布的赏金数据):

是两个示例数据帧,
站点a
站点b
。它们可以在数值列
lat
lon
以及
sitename
列上匹配。了解如何在a)仅
lat
+
lon
,b)
sitename
或c)两者上实现这一点将非常有用

您可以找到作为要点发布的文件的来源

理想情况下,答案将以

merge(sites_a, sites_b, by = **magic**)

agrep
函数(base R的一部分),它使用进行近似字符串匹配,可能值得一试。如果不知道您的数据是什么样子的,我就无法真正提出有效的解决方案。但这是一个建议。。。它将匹配记录在一个单独的列表中(如果有多个同样好的匹配,那么也会记录这些匹配)。假设您的data.frame被称为
df

l <- vector('list',nrow(df))
matches <- list(mother = l,father = l)
for(i in 1:nrow(df)){
  father_id <- with(df,which(student_name[i] == father_name))
  if(length(father_id) == 1){
    matches[['father']][[i]] <- father_id
  } else {
    old_father_id <- NULL
    ## try to find the total                                                                                                                                 
    for(m in 10:1){ ## m is the maximum distance                                                                                                             
      father_id <- with(df,agrep(student_name[i],father_name,max.dist = m))
      if(length(father_id) == 1 || m == 1){
        ## if we find a unique match or if we are in our last round, then stop                                                                               
        matches[['father']][[i]] <- father_id
        break
      } else if(length(father_id) == 0 && length(old_father_id) > 0) {
        ## if we can't do better than multiple matches, then record them anyway                                                                              
        matches[['father']][[i]] <- old_father_id
        break
      } else if(length(father_id) == 0 && length(old_father_id) == 0) {
        ## if the nearest match is more than 10 different from the current pattern, then stop                                                                
        break
      }
    }
  }
}

l这将获取一个常见列名列表,根据所有组合列的
agrep
进行匹配,然后如果
all.x
all.y
等于TRUE,则会在缺失列中添加不匹配的记录,并用NA填充。与
merge
不同,每个数据帧中要匹配的列名必须相同。挑战似乎是正确设置
agrep
选项以避免虚假匹配

  agrepMerge <- function(df1, df2, by, all.x = FALSE, all.y = FALSE, 
    ignore.case = FALSE, value = FALSE, max.distance = 0.1, useBytes = FALSE) {

    df1$index <- apply(df1[,by, drop = FALSE], 1, paste, sep = "", collapse = "")
    df2$index <- apply(df2[,by, drop = FALSE], 1, paste, sep = "", collapse = "")

    matches <- lapply(seq_along(df1$index), function(i, ...) {
      agrep(df1$index[i], df2$index, ignore.case = ignore.case, value = value,
            max.distance = max.distance, useBytes = useBytes)
    })

    df1_match <- rep(1:nrow(df1), sapply(matches, length))
    df2_match <- unlist(matches)

    df1_hits <- df1[df1_match,]
    df2_hits <- df2[df2_match,]

    df1_miss <- df1[setdiff(seq_along(df1$index), df1_match),]
    df2_miss <- df2[setdiff(seq_along(df2$index), df2_match),]

    remove_cols <- colnames(df2_hits) %in% colnames(df1_hits)

    df_out <- cbind(df1_hits, df2_hits[,!remove_cols])

    if(all.x) {
      missing_cols <- setdiff(colnames(df_out), colnames(df1_miss))
      df1_miss[missing_cols] <- NA
      df_out <- rbind(df_out, df1_miss)
    }
    if(all.x) {
      missing_cols <- setdiff(colnames(df_out), colnames(df2_miss))
      df2_miss[missing_cols] <- NA
      df_out <- rbind(df_out, df2_miss)
    }
    df_out[,setdiff(colnames(df_out), "index")]
}

agrepMerge谢谢,nullglob。请您解释一下使用数据帧(x,y)和变量(学生姓名等)的语法。对不起@user702432,我没有仔细阅读您的问题。您已经找到了
agrep
。我添加了一个建议,说明如何将其与您的数据结合使用。Frame您能否提供您的数据的一小部分(或向我们提供一些虚假数据)?@RomanLuštrik虽然这本来不是我的问题,但我也遇到了类似的问题,创建了一些示例数据,并提供了奖励。@David您是否尝试过
merge(sites_a,sites_b,by=c(“lon”,“lat”))
?在您的情况下,如果您想按名称合并,您必须投入更多精力使两个数据帧中的名称匹配(祝您好运,嗯)。@RomanLuštrik在本例中,坐标具有不同的精度级别。因此,
轮上的匹配(sites_b[,c('lat','lon')],2)
将非常接近-除非出现符号错误。请将此作为要点: