代码之家  ›  专栏  ›  技术社区  ›  blazej

在R中用混乱的列名连接两个数据帧

  •  1
  • blazej  · 技术社区  · 6 年前

    给出这些示例性数据集(1和2):

    如何合并每个数据集(1和2) 使用 codes 数据集,以便 codes$id 是否已映射(同步?)到 colnames 属于 dataset1 dataset2 他们匹配的地方。

    代码 是描述测量站的数据对象。
    数据集1 数据集2 一些测站的测量结果列命名混乱-除了“测站”之外,没有实际的模式 # “零件。

    codes<- data.frame(
          id=c("MotherStation", "station2", "station3",
               "station4", "stationFive", "station6"),
          id2=c("a", "b", "c", "d", "e", "f"),
          var1= seq(1:6),
          var2= seq(1:6))
    
    dataset1 <- data.frame("291_hhaMotherStation_1g44" = rnorm(6), 
                            "143_wwaStation4_1d21"=rnorm(6))
    
    dataset2 <- data.frame("143_wwaStation4_1d21" = rnorm(6), 
                            "station2WWa" = rnorm(6), 
                            "KrkStation6"=rnorm(6))
    

    我想要的结果是:

    newData1 <- data.frame(MotherStation = dataset1$X291_hhaMotherStation_1g44,
                           station4 = dataset1$X143_wwaStation4_1d21)
    
    newData2 <- data.frame(station4 = dataset2$X143_wwaStation4_1d21,
                           station2 = dataset2$station2WWa,
                           station6 = dataset2$KrkStation6)
    

    我确实觉得 dplyr join s和一些与RegEx匹配的字符串可以让我到达那里,但我被卡住了(几乎每次涉及RegEx时都会发生这种情况)。

    编辑:阅读后 Jennifer 答:我修改了示例代码以匹配更一般的情况,其中 id s英寸 代码 数据帧不一定由粘在其上的唯一数字标识 station ,但实际上只能由字符串表示。

    2 回复  |  直到 6 年前
        1
  •  3
  •   Jennifer Brussow    6 年前

    这里有一个非常棘手的解决方案。我相信有一种更漂亮的方法可以消除循环,但这至少可以让你达到你想要的目的。

    这使两个数据集的名称标准化。

    rename_col <- function(code, dataset){
      index <- grep(code, names(dataset), ignore.case = TRUE)
      names(dataset)[index] <- code
      return(dataset)
    }
    
    for(i in seq_len(nrow(codes))){
      dataset1 <- rename_col(codes[i, "id"], dataset1)
      dataset2 <- rename_col(codes[i, "id"], dataset2)
    }
    

    从那里,您应该可以进行完全联接。

    full_join(dataset1, dataset2)
    
        2
  •  2
  •   erocoar    6 年前

    这应该行得通-首先将所有不在 id 列,然后将其替换为精确的字符串(因为大小写是不规则的)

    dfs <- list(dataset1, dataset2)
    
    
    out <-  lapply(dfs, function(x) {
      colnames(x) <- gsub(paste(".*(", paste(codes$id, collapse = "|"), ").*", sep = ""), 
           "\\1", colnames(x), perl = TRUE, ignore.case = TRUE)
      colnames(x) <- sapply(colnames(x), function(y) as.character(codes$id[tolower(codes$id) == tolower(y)]))
      return(x)
    })
    
    > all.equal(out[[1]], newData1)
    [1] TRUE
    > all.equal(out[[2]], newData2)
    [1] TRUE
    

    并加入:

    library(tidyverse)
    do.call(full_join, out)