Menurut tabel berikut, saya memiliki banyak guru yang berbeda(10,11,12,...) dengan ide yang berbeda(1,2,... misalnya 1:Sangat Baik, 2:Baik,... ) masing-masing kelas (1,2,3,...). Beberapa guru tidak tahu tentang beberapa kelas.

class  Teacher-code  Opinion
     1   12            1
     1   13            1
     1   14            1
     2   11            3
     2   13            1
     3   10            1
     3   11            2
     3   12            1
     3   13            1

Ini adalah contoh tabel saya tetapi saya memiliki banyak catatan. Saya ingin memiliki matriks guru yang simetris dengan jumlah ide yang sama tentang kelas. misalnya, guru 12 dan 13 memiliki ide yang sama di kelas 1 dan 3, maka elemen persimpangannya adalah 2. Atau kode guru 14 dan 13 hanya memiliki satu ide yang sama tentang kelas pertama. Saya ingin mendapatkan matriks berikut:

     [10] [11] [12] [13] [14]
[10]    0    0    1    1    0
[11]    0    0    0    0    0
[12]    1    0    0    2    1
[13]    1    0    2    0    1
[14]    0    0    1    1    0
0
SA12 10 Januari 2021, 19:16

3 jawaban

Jawaban Terbaik

Ini adalah solusi R dasar berdasarkan pendekatan umum yang diambil untuk menemukan baris umum antara bingkai data. Mungkin ini bisa membantu.

Buat fungsi yang akan menemukan tumpang tindih dalam kerangka data Anda antara pengajar yang berbagi nilai umum lainnya di kolom tertentu (dalam hal ini, class dan Opinion). Dengan merge Anda dapat mengidentifikasi tumpang tindih, dan nrow untuk menghitung baris yang tumpang tindih.

Dengan menggunakan outer Anda dapat membuat matriks semua pengajar. Fungsi yang diteruskan ke produk perlu divektorkan.

the_teachers <- sort(unique(df$Teacher_code))

get_num_classes <- function(x, y) {
  nrow(
    merge(
      df[df$Teacher_code == x, c("class", "Opinion")], 
      df[df$Teacher_code == y, c("class", "Opinion")]
    )
  )
}

mat <- outer(the_teachers, the_teachers, Vectorize(get_num_classes))
diag(mat) <- 0
dimnames(mat) <- list(the_teachers, the_teachers)
mat

Keluaran

   10 11 12 13 14
10  0  0  1  1  0
11  0  0  0  0  0
12  1  0  0  2  1
13  1  0  2  0  1
14  0  0  1  1  0

Edit: Berdasarkan komentar, ada minat untuk mengidentifikasi pecahan (pasangan guru berbagi pendapat yang sama di kelas yang sama) / (pasangan guru berbagi kelas yang sama). Membangun logika yang sama, Anda dapat memodifikasi fungsi seperti di bawah ini. Penggabungan terpisah akan menentukan jumlah guru yang berbagi kelas yang sama. Jika angka ini bukan nol, maka akan menentukan jumlah pendapat yang dibagikan di antara pasangan guru. Jika tidak ada kelas yang dibagikan, fungsi hanya akan mengembalikan nol. Tergantung pada ukuran data dan kesesuaian antar guru, hal ini dapat dioptimalkan lebih lanjut.

get_num_classes <- function(x, y) {
  same_class <- nrow(
    merge(
      df[df$Teacher_code == x, "class", drop = F], 
      df[df$Teacher_code == y, "class", drop = F]
    )
  )
  if (same_class != 0) {
    same_opinion <- nrow(
      merge(
        df[df$Teacher_code == x, c("class", "Opinion")], 
        df[df$Teacher_code == y, c("class", "Opinion")]
      )
    )
    return(same_opinion / same_class)
  } else {
    return(0)
  }
}
2
Ben 11 Januari 2021, 13:41

Berikut adalah opsi R dasar dengan mendefinisikan fungsi pengguna f, di mana aggregate + pmin + vecsets::vintersect diterapkan:

library(vecsets)
f <- function(df) {
  u <- aggregate(. ~ Teacher_code, df, I)
  res <- do.call(
    pmin,
    lapply(
      u[c("class", "Opinion")],
      function(x) outer(x, x, FUN = function(...) lengths(Vectorize(vintersect)(...)))
    )
  )
  `dimnames<-`(`diag<-`(res, 0), rep(list(u[["Teacher_code"]]), 2))
}

Dan kamu akan lihat

> f(df)
   10 11 12 13 14
10  0  0  1  1  0
11  0  0  0  0  0
12  1  0  0  2  1
13  1  0  2  0  1
14  0  0  1  1  0
2
ThomasIsCoding 10 Januari 2021, 20:24

Maksud saya ini adalah beberapa kode yang cukup mengerikan (saya yakin seseorang dapat melakukan sesuatu yang lebih baik) tetapi saya pikir itu memberi Anda hasil yang Anda butuhkan (ini bukan pekerjaan rumah kan -.-?). Juga di masa depan akan lebih mudah jika Anda memberikan data menggunakan dput()

library(dplyr)
library(tidyr)


dat <- tibble(
    class = c( 1,1,1,2,2,3,3,3,3),
    Teacher_code = c(12,13,14,11,13,10,11,12,13),
    Opinion = c(1,1,1,3,1,1,2,1,1)
)

dat2 <- complete(dat, class, Teacher_code)
classes <- unique(dat2$class)
teachers <- unique(dat2$Teacher_code)
len_teachers <- length(teachers)

mat <- matrix(nrow = len_teachers, ncol = len_teachers)

for(i in seq_along(teachers)){
    for( j in seq_along(teachers)){
        same_opinion <- 0
        for(k in classes){
            opinion_i <- dat2 %>% filter(Teacher_code == teachers[[i]] , class == k) %>% pull(Opinion)
            opinion_j <- dat2 %>% filter(Teacher_code == teachers[[j]] , class == k) %>% pull(Opinion)
            same_opinion <- same_opinion + (opinion_i == opinion_j & !(is.na(opinion_i) | is.na(opinion_j)))
        }
        mat[i,j] <- same_opinion
    }
}
0
gowerc 10 Januari 2021, 17:00