Есть ли способ использовать dplyr different (), чтобы считать одинаковые значения равными? - PullRequest
1 голос
/ 06 апреля 2020

Я должен сделать анализ научных c работ, опубликованных в списке из более чем 20 000 журналов. В моем списке более 450 000 записей, но с несколькими дубликатами (например, бумага с более чем одним автором из разных учреждений появляется более одного раза).

Что ж, мне нужно подсчитать различное количество статей в журнале, но проблема в том, что разные авторы не всегда предоставляют информацию одинаково, и я могу получить что-то вроде следующей таблицы:

JOURNAL          PAPER
0001-1231        A PRE-TEST FOR FACTORING BIVARIATE POLYNOMIALS WITH COEFFICIENTS
0001-1231        A PRETEST FOR FACTORING BIVARIATE POLYNOMIALS WITH COEFFICIENTS
0001-1231        THE P3 INFECTION TIME IS W[1]-HARD PARAMETERIZED BY THE TREEWIDTH
0001-1231        THE P3 INFECTION TIME IS W-HARD PARAMETERIZED BY THE TREEWIDTH
0001-1231        COMPOSITIONAL AND LOCAL LIVELOCK ANALYSIS FOR CSP
0001-1231        COMPOSITIONAL AND LOCAL LIVELOCK ANALYSIS FOR CSP
0001-1231        AIDING EXPLORATORY TESTING WITH PRUNED GUI MODELS
0001-1231        DECYCLING WITH A MATCHING
0001-1231        DECYCLING WITH A MATCHING
0001-1231        DECYCLING WITH A MATCHING
0001-1231        DECYCLING WITH A MATCHING.
0001-1231        DECYCLING WITH A MATCHING
0001-1231        ON THE HARDNESS OF FINDING THE GEODETIC NUMBER OF A SUBCUBIC GRAPH
0001-1231        ON THE HARDNESS OF FINDING THE GEODETIC NUMBER OF A SUBCUBIC GRAPH.
0001-1232        DECISION TREE CLASSIFICATION WITH BOUNDED NUMBER OF ERRORS
0001-1232        AN INCREMENTAL LINEAR-TIME LEARNING ALGORITHM FOR THE OPTIMUM-PATH
0001-1232        AN INCREMENTAL LINEAR-TIME LEARNING ALGORITHM FOR THE OPTIMUM-PATH 
0001-1232        COOPERATIVE CAPACITATED FACILITY LOCATION GAMES
0001-1232        OPTIMAL SUFFIX SORTING AND LCP ARRAY CONSTRUCTION FOR ALPHABETS
0001-1232        FAST MODULAR REDUCTION AND SQUARING IN GF (2 M )
0001-1232        FAST MODULAR REDUCTION AND SQUARING IN GF (2 M)
0001-1232        ON THE GEODETIC NUMBER OF COMPLEMENTARY PRISMS
0001-1232        DESIGNING MICROTISSUE BIOASSEMBLIES FOR SKELETAL REGENERATION
0001-1232        GOVERNANCE OF BRAZILIAN PUBLIC ENVIRONMENTAL FUNDS: ILLEGAL ALLOCATION
0001-1232        GOVERNANCE OF BRAZILIAN PUBLIC ENVIRONMENTAL FUNDS: ILLEGAL ALLOCATION
0001-1232        GOVERNANCE OF BRAZILIAN PUBLIC ENVIRONMENTAL FUNDS - ILLEGAL ALLOCATION

Моя цель - использовать что-то вроде:

data%>%
distinct(JOURNAL, PAPER)%>%
group_by(JOURNAL)%>%
mutate(papers_in_journal = n())

Итак, у меня будет такая информация:

JOURNAL      papers_in_journal
0001-1231    6
0001-1232    7

Проблема в том, что вы можете увидеть некоторые ошибки в названии опубликованных работ. У некоторых есть «точка» в конце; некоторые имеют пробелы или заменяют символы; у некоторых есть другие незначительные изменения, такие как W [1] -HARD и W-HARD. Итак, если я запускаю код, как есть, то, что у меня есть:

JOURNAL      papers_in_journal
0001-1231    10
0001-1232    10

Мой вопрос: есть ли способ рассмотреть запас сходства, либо при использовании Different () или аналогичной команды, так У меня может быть что-то похожее (JOURNAL, PAPER% whithin% 0.95)?

В этом смысле я хочу, чтобы команда рассмотрела:

A PRE-TEST FOR FACTORING BIVARIATE POLYNOMIALS WITH COEFFICIENTS
=
A PRETEST FOR FACTORING BIVARIATE POLYNOMIALS WITH COEFFICIENTS

THE P3 INFECTION TIME IS W[1]-HARD PARAMETERIZED BY THE TREEWIDTH
=
THE P3 INFECTION TIME IS W-HARD PARAMETERIZED BY THE TREEWIDTH

DECYCLING WITH A MATCHING
=
DECYCLING WITH A MATCHING.

etc.

Я думаю, что не существует такого простого решения с использованием Different (), и я не смог найти альтернативных команд для этого. Поэтому, если это невозможно, и вы можете предложить какой-либо алгоритм устранения неоднозначности, который я мог бы использовать, я также признателен.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 06 апреля 2020

Один из вариантов - использовать agrep с lapply, чтобы найти индексы статей журнала, которые отличаются на ≤10% (по умолчанию для agrep, который можно изменить с помощью max.distance аргумент), затем возьмите первую статью каждой и векторизуйте ее, используя sapply, получите индексы unique, длину вектора и оберните tapply вокруг всего этого, чтобы выбрать количество "разнородных" статей внутри каждого журнала.

  tapply(data$PAPER, data$JOURNAL, FUN=function(x) {
      length(unique(sapply(lapply(x, function(y) agrep(y, x) ), "[", 1))
     } )

# 0001-1231 0001-1232 
#         6         8 

Для версии dplyr, которая возвращает результаты в более хорошем формате, я поместил приведенный выше код в функцию, затем использовал group_by(), за которым следует summarise().

dissimilar <- function(x, distance=0.1) {
  length(unique(sapply(lapply(x, function(y) 
     agrep(y, x, max.distance = distance) ), "[", 1)))
}

При определении «отличного» в соответствии с документацией agrep.

library(dplyr)

data2 %>%
  group_by(JOURNAL) %>%
  summarise(n=dissimilar(PAPER))

# A tibble: 2 x 2
  JOURNAL       n
  <chr>     <int>
1 0001-1231     6
2 0001-1232     8

Однако для более крупного набора данных, например, содержащего тысячи журналов и более 450 000 статей, выше будет довольно медленно (около 10-15 минут на моем 2,50 ГГц Intel). Я понял, что функция dissimilar неоправданно сравнивает каждый ряд с каждым другим, что бессмысленно. В идеале каждый ряд должен сравниваться только с самим собой и со всеми оставшимися рядами . Например, первый журнал содержит 5 очень похожих статей в строках 8-12. Одно использование agrep в строке № 8 возвращает все 5 индексов, и, следовательно, нет необходимости сравнивать строки 9-12 с любыми другими. Поэтому я заменил lapply на a для l oop, и теперь процесс занимает всего 2-3 минуты с набором данных из 450 000 строк.

dissimilar <- function(x, distance=0.1) {
  lst <- list()               # initialise the list
  k <- 1:length(x)            # k is the index of PAPERS to compare with
  for(i in k){                # i = each PAPER, k = itself and all remaining
    lst[[i]] <- agrep(x[i], x[k], max.distance = distance) + i - 1 
                              # + i - 1 ensures that the original index in x is maintained
    k <- k[!k %in% lst[[i]]]  # remove elements which are similar
  }
  lst <- sapply(lst, "[", 1)  # take only the first of each item in the list
  length(na.omit(lst))        # count number of elements
}

Теперь разверните исходный примерный набор данных так, чтобы 450 000 записей, содержащих около 18 000 журналов, каждая из которых содержит около 25 статей.

n <- 45000
data2 <- do.call("rbind", replicate(round(n/26), data, simplify=FALSE))[1:n,]
data2$JOURNAL[27:n] <- rep(paste0("0002-", seq(1, n/25)), each=25)[1:(n-26)]

data2 %>%
  group_by(JOURNAL) %>%
  summarise(n=dissimilar(PAPER))

# A tibble: 18,001 x 2
   JOURNAL        n
   <chr>      <int>
 1 0001-1231      6 # <-- Same
 2 0001-1232      8
 3 0002-1        14
 4 0002-10       14
 5 0002-100      14
 6 0002-1000     13
 7 0002-10000    14
 8 0002-10001    14
 9 0002-10002    14
10 0002-10003    14

# ... with 17,991 more rows

Задача состоит в том, чтобы найти способ еще больше ускорить процесс.

0 голосов
/ 06 апреля 2020

Вы хотите использовать пакет, предназначенный для обработки естественного языка. Попробуйте пакет quanteda.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...