Мне нужно создать уникальные пары слов в R или Excel - PullRequest
0 голосов
/ 05 февраля 2019

У меня 2 списка с названиями городов.оба списка содержат одинаковые названия городов.Я должен создать городские пары из этих списков.Так, например, 1-й список содержит такие имена, как Лондон, Париж, Москва, Женева и Токио.Список 2 содержит точно такие же имена.Однако третий список должен содержать пары типа «Лондон-Париж», «Лондон-Токио», «Лондон-Женева» и т. Д., Но не «Токио-Лондон» или «Париж-Лондон», так как это будет двойной счет.Буду признателен за любую помощь в R или Excel.

Я пытался использовать функцию 'combn' в R. Однако у меня есть около 4500 наблюдений, и функция 'combn' не работала для меня.

Ответы [ 5 ]

0 голосов
/ 05 февраля 2019

Мы можем попытаться приготовить нашу собственную функцию, чтобы найти комбинации названий городов. Она работает немного быстрее, по сравнению с combn():

функция

combn2 <- function(x){
  n = length(x)
  paste(
    x[rep.int(seq_along(x)[-n], times = rev(seq_along(x))[-1])], 
    x[unlist(lapply(seq_along(x)[-1], ':', to = n))], 
    sep = '-'
  )
}

проверить, если результатыправильное

cities  <- list("London", "Paris", "Kyiv", "Geneva", "Tokyo")

combn2(cities)

# [1] "London-Paris"  "London-Kyiv"   "London-Geneva" "London-Tokyo"  "Paris-Kyiv"   
# [6] "Paris-Geneva"  "Paris-Tokyo"   "Kyiv-Geneva"   "Kyiv-Tokyo"    "Geneva-Tokyo" 

сравнение времени для combn() и combn2() для городов 5К

данные
cities <- unique(maps::world.cities$name)

length(cities)

# [1] 41074

cities <- cities[1:5000]
время для combn()
system.time(
  combn(cities, 2, paste, collapse = "-")
)

#   user  system elapsed 
# 116.02    0.01  116.33 
время для combn2()
system.time(
  combn2(cities)
)

#  user  system elapsed 
# 14.04    0.00   14.09 

IЯ думаю, что большую часть времени тратит paste(), поэтому, если вы найдете способ ядеризации paste(), я был бы очень признателен, если бы вы сообщили мне, как вы это сделали.

0 голосов
/ 05 февраля 2019

Вы также можете сделать это в Excel.Создайте новый модуль, вставьте следующий код, обновите диапазон в первых двух строках кода и выполните макрос VBA:

Sub combn_VBA()
    'Define variables
    Dim CityListSourceRange As Range: Set CityListSourceRange = Sheet1.Range("A1:A5") '<-- Replace A5:A9 with range address containing the city names
    Dim CityCombinationDestinyRange As Range: Set CityCombinationDestinyRange = Sheet1.Range("C1") '<-- Replace C1 with first cell where you want to place the result list
    Set CityList = CreateObject("Scripting.Dictionary")

    'Copies the source cities into a collection
    For Each CellX In CityListSourceRange
        i = i + 1
        CityList.Add CellX.Value, i
    Next CellX

    'Creates unique pairs
    For Each City1 In CityList
        For Each City2 In CityList
            If CityList(City1) < CityList(City2) Then
                CityCombinationDestinyRange.Offset(j, 0).Value = City1 & "-" & City2
                j = j + 1
            End If
        Next City2
    Next City1
End Sub

Чтобы получить что-то вроде этого:

result

0 голосов
/ 05 февраля 2019

Использование файла расширения .grid, а затем манипулирование:

# create all possible combinations
df <- expand.grid(myList, myList)

# ensure only 1 combination for each pair
df <- as.data.frame(unique(t(apply(df, 1, sort))))

# remove same city combinations
df <- subset(df, df$V1 != df$V2)

# create column with pairs
df$combo <- paste0(df$V1, "-", df$V2)
0 голосов
/ 05 февраля 2019

Для Excel - VBA :

Мы можем использовать крошечный трюк:

Поскольку списки идентичны, мы можем решить проблему только одним списком:

Sub MakePairs()
    Dim i As Long, N As Long, k As Long, j As Long

    N = Cells(Rows.Count, "A").End(xlUp).Row
    k = 1

    For i = 1 To N - 1
        For j = i + 1 To N
            Cells(k, 3).Value = Cells(i, 1).Value & "-" & Cells(j, 1).Value
            k = k + 1
        Next j
    Next i
End Sub

enter image description here

ПРИМЕЧАНИЕ:

  1. этот метод позволяет избежать нежелательных перестановок существующих пар
  2. этот метод позволяет избежать повторяющихся пар, таких как Лондон-Лондон
0 голосов
/ 05 февраля 2019

(для этого вам не нужен второй список, достаточно одного)

cities  <- list("London", "Paris", "Kyiv", "Geneva", "Tokyo")

combn(cities, 2, paste, collapse = "-")

# [1] "London-Paris"  "London-Kyiv"   "London-Geneva" "London-Tokyo"  "Paris-Kyiv"   
# [6] "Paris-Geneva"  "Paris-Tokyo"   "Kyiv-Geneva"   "Kyiv-Tokyo"    "Geneva-Tokyo" 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...