6

私はデータフレームを持っています

test <- structure(list(
     y2002 = c("freshman","freshman","freshman","sophomore","sophomore","senior"),
     y2003 = c("freshman","junior","junior","sophomore","sophomore","senior"),
     y2004 = c("junior","sophomore","sophomore","senior","senior",NA),
     y2005 = c("senior","senior","senior",NA, NA, NA)), 
              .Names = c("2002","2003","2004","2005"),
              row.names = c(c(1:6)),
              class = "data.frame")
> test
       2002      2003      2004   2005
1  freshman  freshman    junior senior
2  freshman    junior sophomore senior
3  freshman    junior sophomore senior
4 sophomore sophomore    senior   <NA>
5 sophomore sophomore    senior   <NA>
6    senior    senior      <NA>   <NA>

そして、次のように、学生のカテゴリが連続して変更されるたびに、頂点/エッジ リスト (igraph で使用するため) を作成する必要がありますが、変更がない場合は無視します。

testvertices <- structure(list(
 vertex = 
  c("freshman","junior", "freshman","junior","sophomore","freshman",
    "junior","sophomore","sophomore","sophomore"),
 edge = 
  c("junior","senior","junior","sophomore","senior","junior",
    "sophomore","senior","senior","senior"),
 id =
  c("1","1","2","2","2","3","3","3","4","5")),
                       .Names = c("vertex","edge", "id"),
                       row.names = c(1:10),
                       class = "data.frame")
> testvertices
      vertex      edge id
1   freshman    junior  1
2     junior    senior  1
3   freshman    junior  2
4     junior sophomore  2
5  sophomore    senior  2
6   freshman    junior  3
7     junior sophomore  3
8  sophomore    senior  3
9  sophomore    senior  4
10 sophomore    senior  5

この時点で、ID を無視しています。グラフはエッジをカウントで重み付けする必要があります (つまり、新入生 -> ジュニア = 3)。アイデアは、ツリー グラフを作成することです。メインの交換ポイントのそばにあることは知っていますが、それはあなたが尋ねる場合に備えて...

4

2 に答える 2

3

私があなたを正しく理解していれば、次のようなものが必要です。

elist <- lapply(seq_len(nrow(test)), function(i) {
  x <- as.character(test[i,])
  x <- unique(na.omit(x))
  x <- rep(x, each=2)
  x <- x[-1]
  x <- x[-length(x)]
  r <- matrix(x, ncol=2, byrow=TRUE)
  if (nrow(r) > 0) { r <- cbind(r, i) } else { r <- cbind(r, numeric()) }
  r
})

do.call(rbind, elist)

#                              i  
# [1,] "freshman"  "junior"    "1"
# [2,] "junior"    "senior"    "1"
# [3,] "freshman"  "junior"    "2"
# [4,] "junior"    "sophomore" "2"
# [5,] "sophomore" "senior"    "2"
# [6,] "freshman"  "junior"    "3"
# [7,] "junior"    "sophomore" "3"
# [8,] "sophomore" "senior"    "3"
# [9,] "sophomore" "senior"    "4"
#[10,] "sophomore" "senior"    "5"

これは最も効率的な解決策ではありませんが、かなり教訓的だと思います。入力行列の行ごとにエッジを個別に作成するため、lapply. 行からエッジを作成するには、まず NA と重複を削除してから、各頂点を 2 回含めます。最後に、最初と最後の頂点を削除します。このようにして、エッジ リスト マトリックスを作成しました。最初と最後の頂点を削除して、2 つの列にフォーマットするだけです (実際には、ベクトルのままにしておく方が効率的ですが、気にしないでください)。

余分な列を追加するときは、エッジ リスト マトリックスにゼロ行があるかどうかを注意深く確認する必要があります。

このdo.call関数は、すべてを接着するだけです。結果は行列で、必要に応じて を介してデータ フレームにas.data.frame()変換できます。次に、3 番目の列を数値に変換することもできます。必要に応じて列名を変更することもできます。

于 2012-09-12T06:23:26.707 に答える
1

これはあなたが望むことをしますか...

test1<-c(test[[2]],test[[3]],test[[4]])
test2<-c(test[[3]],test[[4]],test[[5]])
df<-data.frame(vertex=test1,edge=test2)
df1<-df[complete.cases(df),]
result<-df1[df1$vertex != df1$edge,]
于 2012-09-11T08:58:35.993 に答える