2016-10-12 7 views
0

リスト内にdata.frameオブジェクトもあります。これらのオブジェクトも、後で処理するために望ましい方法で操作されます。しかし、私は与えられた条件の各リストの補集合を取ろうと思っています。また、単にこの作業を行うためのヘルパー関数をスケッチします。私はdplyrパッケージからsetdiff関数を使っていましたが、これは正しい方法です。しかし、出力は私が期待したものではないことが判明しました。ネストされたリストに対してヘルパー関数を使用する方法を試しましたが、パラメータを変更すると出力が正しくありませんでした(type = c( "Bio"、 "Tech"))。私が期待したクリーンな、よく構築された出力を得るための迅速なアプローチはありますか?これをどうすればいいのですか?何か案が ?listのdata.frameを操作するときの出力を容易にする方法はありますか?

迅速な再現性の例:

savedList <- list(
    foo_saved = data.frame(v1=c(1,6,16), v2=c(4,12,23), nm=c("a1","a2","a3")), 
    bar_saved = data.frame(v1=c(7,19,31), v2=c(13,28,43), nm=c("b3","b6","b7")), 
    cat_saved = data.frame(v1=c(5,21,36), v2=c(11,29,42), nm=c("c2","c4","c9")) 
) 

dropedList <- list(
    foo_droped = data.frame(v1=c(6,25,40), v2=c(12,33,49),nm=c("a2","a5","a8")), 
    bar_droped = data.frame(v1=c(15,19,47), v2=c(18,28,55),nm=c("b4","b6","b9")), 
    cat_droped = data.frame(v1=c(13,21,36,53), v2=c(19,29,42,67),nm=c("c3","c4","c9","c12")) 
) 

私はリストを操作するために、このトリックを使用:

x <- c(savedList, dropedList) 
newList <- split(x, sub("_.*", "", names(x)))[sub("_.*", "", names(savedList))] 

これは私が実装しようとするヘルパー関数です:

func <- function(list, type=c("Bio", "Tech")) { 
    type=match.arg(type) 
    if(type=="Bio") list[[1]] else setdiff(list[[1]], list[[2]]) 
} 

私がしましたおそらく私の出力を達成するこの方法:

res <- Map(func, newList) 

私は "Tech"としてタイプを設定すると動作しませんが、setdiffは私が期待した補完セットを返すことができませんでした。また、マップを使用すると、タイプを変更して別の出力を得るのが難しいです。希望の出力を得るための効率的な方法はありますか?

次に、条件付きで各リストの補集合を取りたいと思います。

所望の出力タイプは「バイオ」の場合:

output.Bio <- list(
    foo_otp = data.frame(v1=c(1,6,16), v2=c(4,12,23), nm=c("a1","a2","a3")), 
    bar_otp = data.frame(v1=c(7,19,31), v2=c(13,28,43), nm=c("b3","b6","b7")), 
    cat_otp = data.frame(v1=c(5,21,36), v2=c(11,29,42), nm=c("c2","c4","c9")) 
) 

所望の出力タイプが「技術」である場合:

output.Tech <- list(
    foo_otp = data.frame(v1=c(1,16),v2=c(4,23),nm=c("a1","a3")), 
    bar_otp = data.frame(v1=c(7,31),v2=c(13,43),nm=c("b3","b7")), 
    cat_otp = data.frame(v1=c(5),v2=(11),nm="c2") 
) 

私はヘルパー関数で何が悪かったのかを把握することはできません。ヘルパー機能がより安全に機能することを確認するための提案はありますか?希望の出力をより効率的に得るために、このタスクをどのように達成できますか?ありがとうございました

答えて

1

data.frameの違いを調べていますが、これはanti_joinからdplyrまでです。これは、あなたのoutput.Techを与える:

Map(anti_join, savedList, dropedList) 

#Joining by: c("v1", "v2", "nm") 
#Joining by: c("v1", "v2", "nm") 
#Joining by: c("v1", "v2", "nm") 
#$foo_saved 
# v1 v2 nm 
#1 16 23 a3 
#2 1 4 a1 

#$bar_saved 
# v1 v2 nm 
#1 7 13 b3 
#2 31 43 b7 

#$cat_saved 
# v1 v2 nm 
#1 5 11 c2 

あなただけの簡単な関数にし、あなたのコードのこの部分を組み込みたい場合は:明示的に型パラメータを選択し、あなたのソリューションを続行する任意の方法

func = function(L1, L2, type) 
{ 
    if(!type %in% c('Bio','Tech')) stop('Wrong type') 
    if(type=='Bio') return(L1) 
    Map(anti_join, L1, L2) 
} 

#func(savedList, dropedList, 'Tech') 
#func(savedList, dropedList, 'Bio') 
+0

を?このソリューションをより互換性のあるものにする方法は?私はタイプを "Bio"または "Tech"として設定し、対応する出力を得たいと思っています。 –

+1

私はこれを統合するために私の答えを豊かにしました...あなたのコードにあなたの質問への答えを統合するあなたの役割にもかかわらず:) –

+0

素晴らしい。 anti_joinが最初の3行を与えるのはなぜですか?どうすればこれを避けることができますか? anti_joinのための良い選択肢? –

関連する問題