2017-06-15 6 views
3

私はdata.tableでlapplyを動的に使用する方法は?

set.seed(18) 
library(data.table) 
site1 <- data.table(id = 1:10, A = c(sample(c(NA, letters[1:10]),10)), 
        B = sample(c(NA, LETTERS[1:7]), 10, replace = T), 
        C = sample(c(NA, 1:4), 10, replace = T)) 

site2 <- data.table(id = c(1:4, sample(5:15, 6)), 
        A = c(NA, NA, NA, sample(letters, 1), NA, NA, NA, sample(letters, 1), NA, NA), 
        B = sample(LETTERS, 10), d = sample(1:5, replace = T)) 

とこの機能の目標は「NAがある場合、変数はsite1site2の両方にあり、ものを見るためにある

col.smash <- function(a, b, linkvars){ 
  require(data.table) 
  
  ##### CONVERT TO DATA.TABLES FOR EASIER USE, AND MERGE 
  if(dim(a)[1] <= dim(b)[1]){ 
    c <- data.table(a); setkeyv(c, linkvars) 
    d <- data.table(b); setkeyv(d, linkvars) 
  } else { 
    c <- data.table(b); setkeyv(c, linkvars) 
    d <- data.table(a); setkeyv(d, linkvars) 
  } 
  
  k <- c[d] 
  
  rep.list<- names(a)[names(a) %in% names(b) & !(names(a) %in% linkvars)] 
  i.combo <- paste0("i.",rep.list) 

  f <- k[ , (rep.list) := lapply(.SD, function(x){ifelse(is.na(x), 
                get("i.", names(x)), x)}), 
      .SDcols = rep.list] 
  return(f) 
  } 

ように見える関数として見えるデータセットを持っています「で、 site2$Aの対応する値で置き換え、 site1$Aを言うことができます。 ifelse文が唯一の「NA」と一つの変数をチェックする理由です site2オーバー site1の階層は、あります。

条件が正常に動作していないされた後、私は、最初のifelse結果(get("i.",names(x)))のでlapply機能でエラーを取得しています。この場合、次のエラーが発生します。

私はわかりません。理想的には、私はなるだろうことは、

id A B C d 
1: 1 i E NA 4 
2: 2 g F NA 4 
3: 3 h NA 4 1 
4: 4 x B 4 2 
5: 5 j G NA NA 
6: 6 c NA 3 4 
7: 7 a D 2 NA 
8: 8 b NA 2 NA 
9: 9 d G 1 4 
10: 10 f NA 1 NA 
11: 12 NA V NA 2 
12: 13 n J NA 1 
13: 14 NA T NA 1 
14: 15 NA X NA 1 

だから、私は実際には2つの問題を抱えている変数ABCi.ADはなく、のようなi.Bsite1site2内のすべての値を持つdata.tableだと思います。最初は誤りであり、第二は、私は私の機能にk内のすべての行を取得しておりませんということです。彼らは関連していないようです。

何か助けていただければ幸いです。

また、ブラウニーは、誰でも信じられないほどcol.smashを参照できると指摘しています。

+0

のようなものあなたはrbind-INGで一つの長いdata.tableを作る場合は、= 'グループによる'で集計操作としてこれを行うことができます'site1'と' site2'はお互いの下にあります。 – thelatemail

+0

明確にするために、あなたは完全な列について話していますよね?言い換えれば、 "NA"がある場合、 'site1 $ A'は' site2 $ A'_の対応する値で置き換えます。これは、あなたが行を置換する_を求めていることを示唆しています。しかし、この場合、期待される結果は列「B」の行3に「C」を示す。 – Uwe

+0

@UweBlock私はあなたの質問を理解していません。 – akash87

答えて

3

This function's goal is to see what variables are in both site1 and site2 and if there is an "NA" in, lets say site1$A , replace it with the corresponding value in site2$A . There is a hierarchy of site1 over site2

出力は、それが

仕組み

id A B C d 
1: 1 i E NA 4 
2: 2 g F NA 4 
3: 3 h NA 4 1 
4: 4 NA B 4 2 
5: 5 j G NA NA 
6: 6 c NA 3 4 
7: 7 a D 2 NA 
8: 8 b NA 2 NA 
9: 9 d G 1 4 
10: 10 f NA 1 NA 
11: 12 NA V NA 2 
12: 13 n J NA 1 
13: 14 NA T NA 1 
14: 15 NA X NA 1 

を与える

g <- function(d1, d2, byvars){ 
    D = funion(d1[, ..byvars], d2[, ..byvars]) 

    d2vars = setdiff(names(d2), byvars) 
    D[d2, on=byvars, (d2vars) := mget(sprintf("i.%s", d2vars))] 

    d1vars = setdiff(names(d1), byvars) 
    D[d1, on=byvars, (d1vars) := mget(sprintf("i.%s", d1vars))] 

    setcolorder(D, c(byvars, d1vars, setdiff(d2vars, d1vars))) 
    setorderv(D, byvars)[] 
} 

g(site1, site2, "id") 

のようにあったことができます3210引数は列名のベクトルを許可します。

かなり新しい..構文がdata.table外部に格納された列のインデックスを参照することができます。私はよくある質問と?data.tableを見て、ドキュメントを見つけることができませんでした。今のところ、それはthe first changelog item in 1.10.2 at leastです。

「SITE2オーバーSITE1の階層」を与えるために、我々は最初のサイト2から追加し、次にSITE1ので、それは最後の編集を取得します。

funionの使用は、各テーブル内には重複が存在しないことを前提としています。ある場合は、そのステップに、より複雑なアプローチが必要とされるであろう、おそらく

D = rbind(d1[, ..byvars], d2[,..byvars][!d1, on=byvars]) 
+0

を明確にしてください(私はcol.smashのリファレンスもその機能も理解していないので、実際にはなぜ機能しないのかについてはコメントできません) – Frank

+0

@akrunうん、fsetdiffがあります。ここにどこに合うと思いますか?私はそれを使う方法を考えていましたが、その後は援助を始めました。 – Frank

+0

ハルク・スマッシュ・リファレンスでした。しかし、これに感謝します。 byvarsの前になぜ「..」があるのですか? – akash87