Объединение списка фреймов данных по имени объекта списка - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть фрейм данных df

structure(list(X = 1:12, id = structure(c(2L, 7L, 5L, 4L, 3L, 
1L, 6L, 8L, 9L, 10L, 11L, 12L), .Label = c("B12", "B7", "C2", 
"C9", "D3", "E2", "E6", "R4", "T2", "T3", "T7", "U9"), class = "factor"), 
    age = c(42L, 45L, 83L, 59L, 49L, 46L, 52L, 23L, 24L, 25L, 
    26L, 27L)), class = "data.frame", row.names = c(NA, -12L))

Я разделил людей в приведенном выше фрейме данных на список из 3 матриц под названием list_mat

list(Blue_Banana = structure(c("B7", "E6", "D3", "C9"), .Dim = c(2L, 
2L), .Dimnames = list(NULL, c("target", "partner"))), Gold_Apple = structure(c("C2", 
"B12", "E2", "R4"), .Dim = c(2L, 2L), .Dimnames = list(NULL, 
    c("target", "partner"))), Blue_Orange = structure(c("T2", 
"T3", "T7", "U9"), .Dim = c(2L, 2L), .Dimnames = list(NULL, c("target", 
"partner"))))

Я бы хотелдля группировки матриц на основе ключевых слов в именах их матричных объектов, которые можно найти с помощью

names(list_mat)

Затем я использую функцию из пакета igraph для вычисления степени

list_graph= lapply(list_mat, graph_from_edgelist, directed=TRUE)
cent_list= lapply(list_graph, centr_degree, mode="in")

Чтобы получить действительные оценки в градусах, я буду использовать первый матричный объект внутри list_mat в качестве примера

cent_list[[1]]$res

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

V(list_graph[[1]])$name

Я хочу получить оценки в градусах всех значений в матрицах внутри list_mat, которые содержат строку "Blue" в своем имени, чтобыбыть сопоставлены с их идентификатором в исходном фрейме данных df, и это создаст столбец с именем «Синий», который содержит оценки в градусах идентификаторов в этих матрицах.Затем я хочу сделать то же самое со всеми матрицами, которые имеют «Gold» в названии объектов матрицы внутри list_mat (есть только одна матрица с «Gold» в названии). Окончательный результат будет выглядеть примерно так, как показано на рисунке.внизу, но цифры могут быть разными.

imageenter image description here">

1 Ответ

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

Очевидно, что есть несколько способов достичь этого;вот одинВо-первых,

(blues <- grep("Blue", names(list_graph)))
# [1] 1 3

определяет, какие графики соответствуют «Синему».Тогда

(db <- degree(Reduce(`+`, list_graph[blues]), mode = "in"))
# B7 D3 E6 C9 T2 T7 T3 U9 
#  0  1  0  1  0  1  0  1 
(do <- degree(Reduce(`+`, list_graph[-blues]), mode = "in"))
#  C2  E2 B12  R4 
#   0   1   0   1 

- это степени двух групп.Чтобы вставить это в df, мы можем использовать базовые R merge, как в

merge(merge(df, data.frame(Blue = db), by.x = "id", by.y = "row.names", all.x = TRUE),
      data.frame(Gold = do), by.x = "id", by.y = "row.names", all.x = TRUE)
#     id  X age Blue   Gold
# 1  B12  6  46   NA      0
# 2   B7  1  42    0     NA
# 3   C2  5  49   NA      0
# 4   C9  4  59    1     NA
# 5   D3  3  83    1     NA
# 6   E2  7  52   NA      1
# 7   E6  2  45    0     NA
# 8   R4  8  23   NA      1
# 9   T2  9  24    0     NA
# 10  T3 10  25    0     NA
# 11  T7 11  26    1     NA
# 12  U9 12  27    1     NA

, что дает результат с NA, но на самом деле это может быть более адекватным, так как в этом случае ясно, к какой группе относитсяряд принадлежит.В противном случае, например, в строках 9 и 10 это не будет понятно.


В более общем смысле, мы можем сделать

keywords <- c("Blue", "Gold", "Red", "Purple") # Assuming all those are present
for(k in keywords) {
  idx <- grep(k, names(list_graph))
  deg <- degree(Reduce(`+`, list_graph[idx]), mode = "in")
  df <- merge(df, data.frame(deg), by.x = "id", by.y = "row.names", all.x = TRUE)
  names(df)[ncol(df)] <- k
}

Одна часть, которую стоит объяснить, это

Reduce(`+`, list_graph[idx])

Вместо того, чтобы комбинировать разные «синие» градусы из разных графиков, я сначала объединяю графики, как в g1 + g2 (да, это работает), где полученный граф имеет два компонента g1 и g2, а затемвычислить степени этого суперграфа.Теперь Reduce позволяет суммировать таким образом любое количество графиков, т. Е. Он делает g1 + g2 + ... + gk для всех графиков в list_graph[idx].

...