【问题标题】:finding shared column information - a least common ancestor question查找共享列信息 - 一个最不常见的祖先问题
【发布时间】:2019-03-08 00:15:40
【问题描述】:

我有一个由树状信息列组成的 data.frame 对象。例如,我搜索了一组特征 (query_name) 并返回了一组潜在匹配项 (match_name)。每场比赛都有一个关联的位置,分为continentcountryregiontown

我想解决的问题是,对于给定的query_name,找到所有潜在匹配项共有的位置信息。

例如,用这个示例数据:

query_name <- c(rep("feature1", 3), rep("feature2", 2), rep("feature3", 4))
match_name <- paste0("match", seq(1:9))
continent <- c(rep("NorthAmerica", 3), rep("NorthAmerica", 2), rep("Europe", 4))
country <- c(rep("UnitedStates", 3), rep("Canada", 2), rep("Germany", 4))
region <- c(rep("NewYork", 3), "Ontario", NA, rep("Bayern", 2), rep("Berlin", 2))
town <- c("Manhattan", "Albany", "Buffalo", "Toronto", NA, "Munich", "Nuremberg", "Berlin", "Frankfurt")

data <- data.frame(query_name, match_name, continent, country, region, town)

我们会生成这个 data.frame 对象:

    query_name match_name    continent      country  region      town
1   feature1     match1 NorthAmerica UnitedStates NewYork Manhattan
2   feature1     match2 NorthAmerica UnitedStates NewYork    Albany
3   feature1     match3 NorthAmerica UnitedStates NewYork   Buffalo
4   feature2     match4 NorthAmerica       Canada Ontario   Toronto
5   feature2     match5 NorthAmerica       Canada    <NA>      <NA>
6   feature3     match6       Europe      Germany  Bayern    Munich
7   feature3     match7       Europe      Germany  Bayern Nuremberg
8   feature3     match8       Europe      Germany  Berlin    Berlin
9   feature3     match9       Europe      Germany  Berlin Frankfurt

我希望就如何构造一个将产生以下结果的函数获得建议。请注意,共享位置信息现在使用; 分隔符连接和分隔。

  • Feature1 仅在town 信息上有所不同,因此返回的字符串包含continentregion 信息。
  • Feature2 在regiontown 在此处的两个匹配项中不同,因为两个匹配项之一不包含任何信息。尽管如此,缺乏信息被认为与有信息的值不同,因此特征2匹配的唯一共同点是continentcountry
  • Feature3 包含共享的continentcountry 信息,但regiontown 不同,因此只保留continentcountry

希望输出文件如下所示:

query_name   location_output
feature1    NorthAmerica;UnitedStates;NewYork;
feature2    NorthAmerica;Canada;;
feature3    Europe;Germany;;

感谢您提供的任何建议。 干杯!

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    这是一个选项

    library(tidyverse)
    data %>%
        gather(key, val, -query_name, -match_name) %>%
        select(-match_name, -key) %>%
        group_by(query_name, val) %>%
        add_count() %>%
        group_by(query_name) %>%
        filter(n == max(n)) %>%
        summarise(location_output = paste0(unique(val[!is.na(val)]), collapse = ";"))
    ## A tibble: 3 x 2
    #  query_name location_output
    #  <fct>      <chr>
    #1 feature1   NorthAmerica;UnitedStates;NewYork
    #2 feature2   NorthAmerica;Canada
    #3 feature3   Europe;Germany
    

    【讨论】:

      【解决方案2】:

      这不如@MauritsEvers 的解决方案优雅(它不会自动处理任意数量的级别),但它确保每个location_output 都有所有四个; 分隔符。

      library(dplyr)
      data %>%
        group_by(query_name) %>%
        summarize(continent = ifelse(n_distinct(continent) == 1, first(continent), ""),
                  country = ifelse(n_distinct(country) == 1, first(country), ""),
                  region = ifelse(n_distinct(region) == 1, first(region), ""),
                  town = ifelse(n_distinct(town) == 1, first(town), "")) %>%
        mutate(location_output = paste(continent, country, region, town, sep = ";")) %>%
        select(query_name, location_output)
      

      【讨论】:

        【解决方案3】:
        lapply(split(data, data$query_name), function(x){
            x = x[,-(1:2)]
            r = rle(sapply(x, function(d) length(unique(d))))
            x[1, seq(r$lengths[1])]
        })
        #$feature1
        #     continent      country  region
        #1 NorthAmerica UnitedStates NewYork
        
        #$feature2
        #     continent country
        #4 NorthAmerica  Canada
        
        #$feature3
        #  continent country
        #6    Europe Germany
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-28
          相关资源
          最近更新 更多