4

大きなデータフレームがあります。いくつかの目的のために、次のことを行う必要があります。

  • このデータ フレームで 1 つの列を選択します
  • 選択した列を除く、特定のデータ フレームのすべての行を反復処理します
  • 選択した 1 つの列を除くすべての要素が等しい、このデータ フレームのすべての行を選択します
  • グループ名が行インデックスであり、グループ値が重複行のインデックスであるという方法でそれらをグループ化します。

このタスク用の関数を作成しましたが、ネストされたループが原因で動作が遅くなります。このコードをどのように改善できるか、いくつかのアイデアを得たいと思います。

次のようなデータフレームがあるとします。

  V1 V2 V3 V4
1  1  2  1  2
2  1  2  2  1
3  1  1  1  2
4  1  1  2  1
5  2  2  1  2

そして、このリストを出力として取得したい:

diff.dataframe("V2", conf.new, conf.new)

出力:

$`1`
[1] 1

$`2`
[1] 2

$`3`
[1] 1 3

$`4`
[1] 2 4

$`5`
[1] 5

次のコードは目標を達成しますが、動作が遅すぎます。どうにかして改善することは可能でしょうか?

diff.dataframe <- function(param, df1, df2){
  excl.names <- c(param)
  df1.excl <- data.frame(lapply(df1[, !names(df1) %in% excl.names], as.character), stringsAsFactors=FALSE)
  df2.excl <- data.frame(lapply(df2[, !names(df2) %in% excl.names], as.character), stringsAsFactors=FALSE)
  list.out <- list()

  for (i in 1:nrow(df1.excl)){
     for (j in 1:nrow(df2.excl)){
        if (paste(df1.excl[i,],collapse='') == paste(df2.excl[j,], collapse='')){
          if (!as.character(i) %in% unlist(list.out)){                                                                                                                             
            list.out[[as.character(i)]] <- c(list.out[[as.character(i)]], j)                                                                                                       
          }
        }
     }
  }
  return(list.out)
}
4

1 に答える 1

1

最初にいくつかのデータを生成しましょう

df <- as.data.frame(matrix(sample(2, 20, TRUE), 5))

# Produces df like this
  V1 V2 V3 V4
1  2  1  1  1
2  2  1  2  2
3  1  1  2  2
4  1  2  1  1
5  1  2  1  1

次に、 で行をループしlapplyます。次に、各行がwithのすべての行(それ自体を含む)iと比較されます。差が 1 以下の行は を返し、その他は を使用して数値ベクトルに変換する論理ベクトルを返します。dfapplyTRUEFALSEwhich

lapply(1:nrow(df), function(i)
    apply(df, 1, function(x) which(sum(x != df[i,]) <= 1)))

# Produces output like this
[[1]]
[1] 1

[[2]]
[1] 2 3

[[3]]
[1] 2 3

[[4]]
[1] 4 5

[[5]]
[1] 4 5
于 2012-12-13T12:44:47.353 に答える