2017-02-13 3 views
0

私は以下のサンプルフォーマットのdata.tableを持っています。data.tableの各行に異なる複数引数の関数を適用するにはどうすればよいですか?

dt <- data.table(l = c("apple","ball","cat"), 
       m = c(1,2,3), 
       n = c("I ate apple", "I played ball", "cat ate pudding")) 

Iパターンが他の列(l)から来ると、各行の列(n)にsubを適用します。どうすればいい?

私が探していますが出力され、

   l m    n o 
     1: apple 1  I ate apple  I ate 
     2: ball 2 I played ball I played 
     3: cat 3 cat ate pudding ate pudding 

私はdata.table内代入演算子とアプローチmapply(do.call, list(sub), ...)を使用してみましたがsub(パターン、交換、文字列)の引数をする必要がありますdo.callのネストされたリストと私はこれを正しく書く方法に固執しています。

+2

なぜ 'dt [、Map(sub、l、 ''、n)]'だけではないのですか?編集:それは私に名前付きのベクトル/リストを与えるので、私たちが実際に望むのはリスト 'dt [、o:=(Map(sub、l、 '、n))]]に戻り値をラップすることです。 – Shape

+0

@ Shape君は!私のアプローチは今や不必要に複雑に思えます。私は、「サブ」の代わりに、私は別個の機能のリストを持つことができる方法を考え出していました。あなたのコードは私の場合でも仕事をします。回答として投稿したい場合は、先に進んでください。 – Naumz

+0

@Shape投稿することに同意します。私は 'dt [、mapply(sub、sprintf("?%s? "、l)、" "、n、USE]と一緒に行きます。NAMES = FALSE)] ' - 名前の問題を処理します。パターンにはスペースが含まれている可能性があります(OPはおそらく削除したいと考えています)。 – Frank

答えて

3

は、だから我々は、行方向の計算を行いたい、それがo

mapplyは間違いなく機能の右側家族で新しい列として定義返しますが、mapply(およびsapply)は、彼らの前にリストの中から、それらの出力を簡素化しますそれを返す。 data.tableはリストを愛しています。 Mapは返信を変更しないmapply(..., simplify = FALSE)のショートカットです。

次の計算は、私たちが行っていることですが、まだ正しくはありません。 (data.tableが別々の列としてリスト出力を解釈する)

> dt[, Map(sub, l, '', n)] 
    apple  ball   cat 
1: I ate I played ate pudding 

だから我々はさらに、1つを行くと、我々は後にしている出力を得るために、リストでそれをラップしたい:今、私たちはできる

>dt[, .(Map(sub, l, '', n))] 
      V1 
1:  I ate 
2: I played 
3: ate pudding 

:=

> dt[, o := Map(sub, l, '', n)] 
> dt 
     l m    n   o 
1: apple 1  I ate apple  I ate 
2: ball 2 I played ball I played 
3: cat 3 cat ate pudding ate pudding 

EDITを使用してこれを割り当てる:指摘されたように、これは、リストの列であるoになります。

標準mapplyを使用してこれを避けることができますが、私はMapのワンサイズフィットアプローチを好む傾向があります(各行は1つの出力を作成し、リストに表示されます)。 、これは常に動作します、そして、我々は最後に入力し、変換することができます。)

dt[, o := mapply(sub, l, '', n)]

+2

これは 'dt $ o'を埋め込みリストにするので、' mapply'は実際にはもっと適切だと思います。 – thelatemail

+0

本当に、私の列クラスをチェックすべきです、私はまだ 'Map'を好んでいます。 。私は通常、単純化を信頼していません。 'Map'の動作は常に同じです。私はもう一方の方法を追加します – Shape

+1

あなたは間違っている "data.tableはリストを愛しています。" Data.tableは列のリストを好んでおり、リストである列を許可しますが、後者は作業が面倒で常にあります。 – Frank

1

我々は「L」の内容をINGのpasteことにより、ベクトル化のアプローチを行うことができ、使用することをsubpattern引数として部分文字列を削除して新しい列 'o'を作成する

dt[, o := trimws(sub(paste(l, collapse="|"), "", n))] 
dt 
#  l m    n   o 
#1: apple 1  I ate apple  I ate 
#2: ball 2 I played ball I played 
#3: cat 3 cat ate pudding ate pudding 
関連する問題