Используйте уникальные пары значений столбцов для создания идентификаторов диад в фрейме данных.

Я хочу сгенерировать набор идентификаторов диад для кадра данных двустороннего торгового потока (который закодирован в формате from, to и amount traded), чтобы я мог использовать эти идентификаторы для дальнейшего статистического анализа.

Мой пример данных представлен ниже, из которого я извлек и идентифицировал уникальные диады стран из данных, которые включают США.

# load the example data
trade_flow <- readRDS(gzcon(url("https://www.dropbox.com/s/ep7xldoq9go4f0g/trade_flow.rds?dl=1")))
# extract country dyads
country_dyad <- trade_flow[, c("from", "to")]
# identify unique pairs
up <- country_dyad[!duplicated(t(apply(country_dyad, 1, sort))),]
# extract only unique pairs that involve the US
up <- up[(up$from == "USA") | (up$to == "USA"), ]

## how can I use the unique pair object (up) to generate dyad identifiers and include them as a new column in the trade_flow dataframe

Следующим шагом является сопоставление этих уникальных пар диад из столбцов from и to исходного фрейма данных (trade_flow) и создание списка уникальных идентификаторов диад в качестве нового столбца (скажем, dyad) для df (trade_flow). Это должно выглядеть примерно так, как показано ниже, в котором каждая уникальная диада идентифицируется и кодируется как уникальное числовое значение. Я буду признателен, если кто-то может помочь мне в этом.

from    to  trade_flow  dyad
USA   ITA      5100       2
USA   UKG      4000       1
USA   GMY     17000       3
USA   ITA      4500       2
USA   JPN      2900       4
USA   UKG      6700       1
USA   ROK      7000       5
USA   UKG      2300       1
USA   SAF      1500       6
IND   USA      2400       7

person Chris T.    schedule 11.08.2019    source источник


Ответы (2)


Предполагая, что потоки являются направленными, так что A/B и B/A являются разными потоками, соедините столбцы from и to вместе и преобразуйте в фактор. Внутренние коды, которые использует фактор, это 1, 2, ..., no_of_levels, и для их извлечения используется as.numeric.

transform(DF, dyad = as.numeric(factor(paste(from, to))))

давая:

   from  to trade_flow dyad
1   USA ITA       5100    3
2   USA UKG       4000    7
3   USA GMY      17000    2
4   USA ITA       4500    3
5   USA JPN       2900    4
6   USA UKG       6700    7
7   USA ROK       7000    5
8   USA UKG       2300    7
9   USA SAF       1500    6
10  IND USA       2400    1

Применение назначений, сделанных для подмножества, ко всему

Если мы хотим выполнить это назначение только для подмножества строк DF, например head(DF), а затем использовать эти назначения для всех DF, используя NA для потоков в DF, которых нет в DF0, то сначала выполните назначение диад, как указано выше ( см. первую строку ниже), а затем удалите номера потока из DF0 и извлеките его уникальные строки, используя unique. Наконец, объедините это с DF в первых двух столбцах, используя all.x=TRUE, чтобы несопоставленные строки в DF не удалялись.

DF0 <- transform(head(DF), dyad = as.numeric(factor(paste(from, to))))
merge(DF, unique(DF0[-3]), all.x = TRUE, by = 1:2)

давая:

   from  to trade_flow dyad
1   IND USA       2400   NA
2   USA GMY      17000    1
3   USA ITA       4500    2
4   USA ITA       5100    2
5   USA JPN       2900    3
6   USA ROK       7000   NA
7   USA SAF       1500   NA
8   USA UKG       4000    4
9   USA UKG       2300    4
10  USA UKG       6700    4

Примечание

Ввод в воспроизводимой форме:

Lines <- "from to trade_flow
USA   ITA      5100       
USA   UKG      4000       
USA   GMY     17000       
USA   ITA      4500       
USA   JPN      2900       
USA   UKG      6700       
USA   ROK      7000       
USA   UKG      2300       
USA   SAF      1500       
IND   USA      2400"
DF <- read.table(text = Lines, header = TRUE)
person G. Grothendieck    schedule 11.08.2019
comment
Привет, спасибо за ваш ответ, но если я хочу использовать подмножества диад стран (up) для создания идентификаторов диад для полных данных (trade_flow), оставив остальные наблюдения (строки) как NA (или просто установить их как группу 0), какую часть кода мне следует изменить? Спасибо. - person Chris T.; 11.08.2019
comment
Если вы хотите выполнить назначение для подмножества строк, а затем применить это назначение ко всем строкам, см. добавленный раздел в ответе. - person G. Grothendieck; 11.08.2019
comment
Кажется, что если я рассматриваю диаду i-j как ненаправленную и использую это для сопоставления столбцов from, to в кадре данных и генерирую идентификатор диады для всех строк, которые включают i, j (включая ссылку j-i), он оставит эти строки где from = j и to = i не имеют себе равных. Таким образом, R вернет сообщение об ошибке, показывающее разное количество строк между исходным фреймом данных и списком уникальных диад. - person Chris T.; 12.08.2019
comment
Я предполагаю, что другой способ ответить на мой вопрос: если мы предположим, что диада i-j является ненаправленной, рекомендуемый метод будет считать как i-j, так и j-i разными диадами и назначать каждой из них уникальный числовой индикатор. Есть ли способ назначить один и тот же индикатор диады для пар i-j и j-i? - person Chris T.; 12.08.2019
comment
Использование paste(pmin(as.character(from), as.character(to)), pmax(as.character(from), as.character(to))) приведет к тому, что диады будут назначены ненаправленным образом. - person G. Grothendieck; 13.08.2019

Вот вариант с использованием base R

df1$dyad <- with(df1, as.integer(droplevels(interaction(from, to, 
        lex.order = TRUE))))
df1$dyad
#[1] 3 7 2 3 4 7 5 7 6 1

данные

df1 <- structure(list(from = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 1L), .Label = c("IND", "USA"), class = "factor"), to = structure(c(2L, 
6L, 1L, 2L, 3L, 6L, 4L, 6L, 5L, 7L), .Label = c("GMY", "ITA", 
"JPN", "ROK", "SAF", "UKG", "USA"), class = "factor"), trade_flow = c(5100L, 
4000L, 17000L, 4500L, 2900L, 6700L, 7000L, 2300L, 1500L, 2400L
)), class = "data.frame", row.names = c(NA, -10L))
person akrun    schedule 11.08.2019