поиск информации общего столбца - наименее распространенный вопрос предка - PullRequest
2 голосов
/ 07 марта 2019

У меня есть объект data.frame, состоящий из столбцов информации в виде дерева.Например, я выполнил поиск набора функций (query_name) и вернул набор потенциальных совпадений (match_name).Каждому совпадению соответствует местоположение, которое разделяется на continent, country, region и town.

. Проблема, которую я хотел бы решить, - найти для данного 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, поэтому возвращаемая строка содержит информацию от continent до region.
  • Feature2 не отличается от до region или town в двух совпадениях, поскольку одно из двух совпадений не содержит информации.Тем не менее, отсутствие информации считается отличным от значений с информацией, поэтому единственное, что является общим для совпадений для feature2, это continent и country.
  • Feature3 содержит общую информацию continent и country,но различаются region и town, поэтому сохраняются только continent и country.

В ожидании выходного файла, который выглядит следующим образом:

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

Спасибо за любой совет, который вы можете сэкономить.Ура!

Ответы [ 3 ]

1 голос
/ 07 марта 2019

Вот вариант

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
0 голосов
/ 07 марта 2019
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
0 голосов
/ 07 марта 2019

Это менее изящно, чем решение @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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...