【问题标题】:Comparing two unequal data frame and selecting common values in the order of second data frame比较两个不相等的数据框并按第二个数据框的顺序选择公共值
【发布时间】:2017-08-23 07:03:47
【问题描述】:

我有两个数据框如下:

df1<-data.frame(st=c(1,2,3,4),v1=c(12,14,15,75),v2=c(43,32,12,18))

df1
  st v1 v2
1  1 12 43
2  2 14 32
3  3 15 12
4  4 75 18

df2<-data.frame(st=c(1,2,3,4),v1=c(12,24,35,18),v2=c(48,32,121,82),v3=c(53,11,12,75))

df2
  st v1  v2 v3
1  1 12  48 53
2  2 24  32 11
3  3 35 121 12
4  4 18  82 75

我想要的是在“st”列级别匹配两个数据帧,即对于 df1 中的 st = 1,v1 和 v2 的相应值是 12 和 43。因此,如果 df2 中的 st=1,如果有变量包含这些值,然后我想选择 st,以及 df2 中的那些值。

所以对于上面的例子,输出将是

St values
1     12(coming from v1 in df2)
2     32(coming from v2 in df2)
3     12(coming from v3 in df2)
4     18 75(coming from v1 & v3 in df2)

需要注意的重要一点是,在输出数据框中,所选变量的顺序应与 df2 的顺序相同,如您所见,对于 st = 4,df1 中的值是 75 & 18,与 st = 匹配2,但输出仍然是 18,然后是 75,这是 df2 中的顺序。 df2 中的变量也总是大于 df1。

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    如果我理解正确的话......

    第 0 步。准备数据

    您提到您只想选择符合您的条件的行,但示例数据集的每一行至少有一个匹配项。我对其进行了调整,使得 St=3 不匹配,以证明该行不会在结果中返回。

    df1<-data.frame(st=c(1,2,3,4),v1=c(12,14,15,75),v2=c(43,32,12,18))
    df2<-data.frame(st=c(1,2,3,4),v1=c(12,24,35,18),v2=c(48,32,121,82),v3=c(53,11,13,75))
    

    第 1 步:合并数据集

    combined.df <- rbind(df1 %>% gather(v, n, -st) %>% mutate(df = "df1"),
                         df2 %>% gather(v, n, -st) %>% mutate(df = "df2"))
    
    > head(combined.df)
      st  v  n  df
    1  1 v1 12 df1
    2  2 v1 14 df1
    3  3 v1 15 df1
    4  4 v1 75 df1
    5  1 v2 43 df1
    6  2 v2 32 df1
    

    第 2 步。比较并仅保留来自 df2 的匹配项

    res <- combined.df %>%
      group_by(st) %>%
      mutate(n = ifelse(df=="df1", n, ifelse(n %in% n[df=="df1"], n, NA))) %>%
      ungroup() %>%
      filter(df=="df2", !is.na(n)) %>%
      arrange(st, v)
    # if you just want the values, you can stop here.
    > res
    # A tibble: 4 × 4
         st     v     n    df
      <dbl> <chr> <dbl> <chr>
    1     1    v1    12   df2
    2     2    v2    32   df2
    3     4    v1    18   df2
    4     4    v3    75   df2
    
    
    # this part formats the result to follow that of the desired output
    res <- res %>%
      group_by(st) %>%
      summarise(values = paste(as.character(n), collapse = " ")) %>%
      ungroup()
    > res
    # A tibble: 3 × 2
         st values
      <dbl>  <chr>
    1     1     12
    2     2     32
    3     4  18 75
    

    【讨论】:

      【解决方案2】:

      如果你使用合并功能,你可以用这个匹配创建一个唯一的df:

      new<-merge(df1,df2,by="st")
      
      new
      
        st v1.x v2.x v1.y v2.y v3
      1  1   12   43   12   48 53
      2  2   14   32   24   32 11
      3  3   15   12   35  121 12
      4  4   75   18   18   82 75
      

      如果你愿意,你可以按照你想要的方式订购它。例如:

      new2<-new[,1:2]
      new2$from<-"from v1"
      names(new2)<-c("st","value","from")
      
      
      for(i in 3:ncol(new)){
      new3<-new[,c(1,i)]
      new3$from<-pasteo("from v",i)
      names(new3)<-c("st","value","from")
      new2<-rbind(new2,new3)
      
      }
      

      这不是最有效的方法,但如果你的数据很少,它会起作用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-07
        • 2017-07-04
        • 2023-01-15
        • 2021-08-14
        • 2019-03-29
        • 1970-01-01
        • 1970-01-01
        • 2019-03-17
        相关资源
        最近更新 更多