ডেটা টেবিল বা ইগ্রাফ ব্যবহার করে গ্রুপ দ্বারা তাত্ক্ষণিক প্রতিবেশীদের সন্ধান করুন


14

আমার একটি ডেটা টেবিল রয়েছে :

groups <- data.table(group = c("A", "B", "C", "D", "E", "F", "G"), 
                     code_1 = c(2,2,2,7,8,NA,5),
                     code_2 = c(NA,3,NA,3,NA,NA,2),
                     code_3 = c(4,1,1,4,4,1,8))

group code_1 code_2 code_3
  A      2     NA      4
  B      2      3      1
  C      2     NA      1
  D      7      3      4
  E      8     NA      4
  F     NA     NA      1
  G      5      2      8

আমি যেটি অর্জন করতে চাই তা প্রতিটি গ্রুপের জন্য উপলব্ধ কোডগুলির ভিত্তিতে অবিলম্বে প্রতিবেশীদের সন্ধান করা। উদাহরণস্বরূপ: গ্রুপ এ এর ​​নিকটবর্তী প্রতিবেশী গোষ্ঠী বি, সি আছে কোডের কারণে (কোড_1 সকল গ্রুপের সাথে সমান 2) এবং কোড_3 এর কারণে তাত্ক্ষণিক প্রতিবেশী গ্রুপ ডি, ই রয়েছে (কোড_3 সমস্ত গ্রুপে 4 এর সমান)।

আমি যা চেষ্টা করেছি তা প্রতিটি কোডের জন্য, ম্যাচের উপর ভিত্তি করে প্রথম কলাম (গ্রুপ) উপসেট করে:

groups$code_1_match = list()
for (row in 1:nrow(groups)){

  set(groups, i=row, j="code_1_match", list(groups$group[groups$code_1[row] == groups$code_1]))
}

  group code_1 code_2 code_3          code_1_match
    A      2     NA      4              A,B,C,NA
    B      2      3      1              A,B,C,NA
    C      2     NA      1              A,B,C,NA
    D      7      3      4                  D,NA
    E      8     NA      4                  E,NA
    F     NA     NA      1 NA,NA,NA,NA,NA,NA,...
    G      5      2      8                  NA,G

এই "কিন্ডা" কাজ করে তবে আমি ধরে নেব এটি করার মতো আরও একটি ডাটা টেবিল রয়েছে। আমি চেষ্টা করেছিলাম

groups[, code_1_match_2 := list(group[code_1 == groups$code_1])]

তবে এটি কাজ করে না।

আমি কি এর মোকাবেলায় কিছু স্পষ্ট ডেটা টেবিল ট্রিক মিস করছি?

আমার আদর্শ কেস ফলাফলটি এর মতো দেখাবে (যার জন্য বর্তমানে সমস্ত 3 কলামের জন্য আমার পদ্ধতিটি ব্যবহারের প্রয়োজন হবে এবং তারপরে ফলাফলগুলি সংক্ষেপণ করতে হবে):

group code_1 code_2 code_3    Immediate neighbors
  A      2     NA      4         B,C,D,E
  B      2      3      1         A,C,D,F
  C      2     NA      1         A,B,F
  D      7      3      4           B,A
  E      8     NA      4           A,D
  F     NA     NA      1           B,C
  G      5      2      8           

ইগ্রাফ ব্যবহার করে করা যেতে পারে।
zx8754

1
আমার লক্ষ্য হল একটি সংলগ্ন ম্যাট্রিক্স তৈরি করতে ফলাফলটি ইগ্রাফে খাওয়ানো। যদি আমি এমন কিছু কার্যকারিতা মিস করছি যা এটি করে তবে দয়া করে আমাকে এটি উল্লেখ করুন, এটি সত্যই সহায়ক হবে!
ব্যবহারকারী 2321

1
@ zx8754 দয়া করে জড়িত কোনও সমাধান পোস্ট করার বিষয়টি বিবেচনা করুন igraph, এটি সত্যই আকর্ষণীয় হতে পারে।
tmfmnk

@tmfmnk পোস্ট করেছে, যদিও ভেবেছি এটি করার আরও ভাল igraph উপায় হতে পারে।
zx8754

উত্তর:


10

ইগ্রাফ ব্যবহার করে , ২ য় ডিগ্রি প্রতিবেশী পান, সংখ্যা নোড ফেলে দিন, অবশিষ্ট নোডগুলি পেস্ট করুন।

library(data.table)
library(igraph)

# reshape wide-to-long
x <- melt(groups, id.vars = "group")[!is.na(value)]

# convert to graph
g <- graph_from_data_frame(x[, .(from = group, to = paste0(variable, "_", value))])

# get 2nd degree neighbours
x1 <- ego(g, 2, nodes = groups$group)

# prettify the result
groups$res <- sapply(seq_along(x1), function(i) toString(intersect(names(x1[[ i ]]),
                                                                   groups$group[ -i ])))

#    group code_1 code_2 code_3        res
# 1:     A      2     NA      4 B, C, D, E
# 2:     B      2      3      1 A, C, D, F
# 3:     C      2     NA      1    A, B, F
# 4:     D      7      3      4    B, A, E
# 5:     E      8     NA      4       A, D
# 6:     F     NA     NA      1       B, C
# 7:     G      5      2      8           

অধিক তথ্য

ইগ্রাফ অবজেক্টে রূপান্তর করার আগে আমাদের ডেটা দেখতে কেমন লাগে। আমরা মান 2 সহ কোড 1 নিশ্চিত করতে চাই 2 এর মান 2 সহ কোড 2 থেকে পৃথক etc.

x[, .(from = group, to = paste0(variable, "_", value))]
#     from       to
#  1:    A code_1_2
#  2:    B code_1_2
#  3:    C code_1_2
#  4:    D code_1_7
#  5:    E code_1_8
#  6:    G code_1_5
#  7:    B code_2_3
#  8:    D code_2_3
#  9:    G code_2_2
# 10:    A code_3_4
# 11:    B code_3_1
# 12:    C code_3_1
# 13:    D code_3_4
# 14:    E code_3_4
# 15:    F code_3_1
# 16:    G code_3_8

আমাদের নেটওয়ার্কটি কেমন দেখাচ্ছে তা এখানে: এখানে চিত্র বর্ণনা লিখুন

মনে রাখবেন A..Gনোডগুলি সর্বদা এর মাধ্যমে সংযুক্ত থাকেcode_x_y । সুতরাং আমাদের ২ য় ডিগ্রি অর্জন করতে হবে, ego(..., order = 2)প্রতিবেশীদের ২ য় ডিগ্রি প্রতিবেশী অন্তর্ভুক্ত করতে হবে এবং একটি তালিকা অবজেক্ট প্রদান করবে।

নামগুলি পেতে:

lapply(x1, names)
# [[1]]
# [1] "A"        "code_1_2" "code_3_4" "B"        "C"        "D"        "E"       
# 
# [[2]]
# [1] "B"        "code_1_2" "code_2_3" "code_3_1" "A"        "C"        "D"        "F"       
# 
# [[3]]
# [1] "C"        "code_1_2" "code_3_1" "A"        "B"        "F"       
# 
# [[4]]
# [1] "D"        "code_1_7" "code_2_3" "code_3_4" "B"        "A"        "E"       
# 
# [[5]]
# [1] "E"        "code_1_8" "code_3_4" "A"        "D"       
# 
# [[6]]
# [1] "F"        "code_3_1" "B"        "C"       
# 
# [[7]]
# [1] "G"        "code_1_5" "code_2_2" "code_3_8"

ফলাফলটি উপস্থাপনের জন্য, আমাদের code_x_yনোডগুলি এবং মূল নোড (1 ম নোড) অপসারণ করতে হবে

sapply(seq_along(x1), function(i) toString(intersect(names(x1[[ i ]]), groups$group[ -i ])))
#[1] "B, C, D, E" "A, C, D, F" "A, B, F"    "B, A, E"    "A, D"       "B, C"       ""   

ইগ্রাফের বিশেষজ্ঞ না হয়ে এটিকে সত্যিই অদ্ভুত দেখাচ্ছে। এটি কাজ করে মনে হচ্ছে :) আমি যদি এটি সঠিকভাবে বুঝতে পারি তবে এটি প্রথমে একটি গ্রাফ তৈরি করে যেখানে কোডগুলি নিকটাত্মীয় প্রতিবেশী এবং তারপরে এটি সেই গ্রাফ থেকে দ্বিতীয় প্রতিবেশী হিসাবে প্রকৃত আশেপাশের প্রতিবেশীদের সন্ধান করে?
ব্যবহারকারী 2321

@ ব্যবহারকারী 2321 আরও তথ্য যুক্ত করেছেন, আশা করি এটি আরও পরিষ্কার।
zx8754

1
@ ইউজার 2321 বিটিডব্লিউ মোটেও বিশেষজ্ঞ নয়, যেমন মাঝে মাঝে ইগ্রাফ সমস্যার সমাধান করতে চান। আরও ভাল উপায়ের পরামর্শ দেওয়ার জন্য এখনও কিছু বিশেষজ্ঞের অপেক্ষায় রয়েছি।
zx8754

1
হ্যাঁ, আমি কেবল ক্ষেত্রে অনুদানের প্রস্তাব দিচ্ছি। তবে আসুন 2 দিনের মধ্যে দেখুন :)
ব্যবহারকারী 2321

7

বোধহয় এই কিন্তু অর্জনের তোমাদের আরো কিছু ব্যবহারিক উপায় পারে ভালো কিছু না, গলে এবং যোগদান ব্যবহার করছে:

mgrp <- melt(groups, id.vars = "group")[!is.na(value)]
setkey(mgrp, variable, value)
for (i in seq_along(groups$group)) {
  let = groups$group[i]
  set(
    groups, 
    i = i, 
    j = "inei", 
    value = list(mgrp[mgrp[group == let], setdiff(unique(group), let)])
  )
}

groups
#    group code_1 code_2 code_3    inei
# 1:     A      2     NA      4 B,C,D,E
# 2:     B      2      3      1 A,C,D,F
# 3:     C      2     NA      1   A,B,F
# 4:     D      7      3      4   B,A,E
# 5:     E      8     NA      4     A,D
# 6:     F     NA     NA      1     B,C
# 7:     G      5      2      8       

5

এটি @ সিন্ড্রি_বালদুরের গলিত দ্বারা অনুপ্রাণিত। এই সমাধান:

  1. দলগুলিকে গলে যায়
  2. কোনও কার্তেসিয়ান স্ব-যোগদান করুন।
  3. মেলে এমন সমস্ত গ্রুপ এক সাথে আটকান।
  4. আসল টিটিতে ফিরে যায়
library(data.table)
#> Warning: package 'data.table' was built under R version 3.6.2
groups <- data.table(group = c("A", "B", "C", "D", "E", "F", "G"), code_1 = c(2,2,2,7,8,NA,5), code_2 = c(NA,3,NA,3,NA,NA,2), code_3=c(4,1,1,4,4,1,8))

molten_grps = melt(groups, measure.vars = patterns("code"), na.rm = TRUE)

inei_dt = molten_grps[molten_grps,
            on = .(variable, value),
            allow.cartesian = TRUE
            ][,
              .(inei = paste0(setdiff(i.group, .BY[[1L]]), collapse = ", ")),
              by = group]

groups[inei_dt, on = .(group), inei := inei]

groups
#>     group code_1 code_2 code_3       inei
#>    <char>  <num>  <num>  <num>     <char>
#> 1:      A      2     NA      4 B, C, D, E
#> 2:      B      2      3      1 A, C, D, F
#> 3:      C      2     NA      1    A, B, F
#> 4:      D      7      3      4    B, A, E
#> 5:      E      8     NA      4       A, D
#> 6:      F     NA     NA      1       B, C
#> 7:      G      5      2      8

5

Zx8754 দ্বারা উল্লিখিত হিসাবে এবং এর data.table::meltসাথে ব্যবহার করেcombnigraph::as_adjacency_matrix

library(data.table)
df <- melt(groups, id.vars="group", na.rm=TRUE)[,
    if (.N > 1L) transpose(combn(group, 2L, simplify=FALSE)), value][, (1) := NULL]

library(igraph)
as_adjacency_matrix(graph_from_data_frame(df, FALSE))

আউটপুট:

7 x 7 sparse Matrix of class "dgCMatrix"
  A B C E D G F
A . 1 1 1 1 1 .
B 1 . 2 . 1 1 1
C 1 2 . . . 1 1
E 1 . . . 1 1 .
D 1 1 . 1 . . .
G 1 1 1 1 . . .
F . 1 1 . . . .

বা ব্যবহার না করে igraph

x <- df[, unique(c(V1, V2))]
df <- rbindlist(list(df, data.table(x, x)))
tab <- table(df)   #or xtabs(~ V1 + V2, data=df)
ans <- t(tab) + tab
diag(ans) <- 0L
ans

আউটপুট:

   V1
V2  A B C D E F G
  A 0 1 1 1 1 0 1
  B 1 0 2 1 0 1 1
  C 1 2 0 0 0 1 1
  D 1 1 0 0 1 0 0
  E 1 0 0 1 0 0 1
  F 0 1 1 0 0 0 0
  G 1 1 1 0 1 0 0

1
পদক্ষেপ xtabsহিসাবে একটি অনুরূপ আউটপুট তৈরি করতে পারে igraph?
কোল

এটি সত্যিই সহায়ক এবং (আমার চোখে) মার্জিত উত্তর, ধন্যবাদ!
ব্যবহারকারী 2321

@ কোল, হ্যাঁ ব্যবহার করতে পারেন tableবাxtabs
চিনসুন 12
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.