知っておくべきRdata.tableの記号と演算子

R data.tableコードは、その特別なシンボルと関数を利用すると、より効率的かつエレガントになります。そのことを念頭に置いて、新しい列をサブセット化、カウント、および作成するためのいくつかの特別な方法を見ていきます。

このデモでは、2019年のStack Overflow開発者調査のデータを使用し、約90,000件の回答があります。フォローしたい場合は、StackOverflowからデータをダウンロードできます。

data.tableパッケージがシステムにインストールされていない場合は、CRANからインストールしてから、通常どおりにを使用してロードしlibrary(data.table)ます。まず、データセットの最初の数行だけを読み込んで、データ構造を簡単に調べることができます。data.tableのfread()関数とnrows引数を使用してこれを行うことができます。私は10行で読みます:

data_sample <-fread( "data / Survey_results_public.csv"、nrows = 10)

ご覧のとおり、調査する列は85個あります。(すべての列の意味を知りたい場合は、ダウンロードにデータスキーマと元の調査のPDFを含むファイルがあります。) 

すべてのデータを読み込むには、次を使用します。

mydt <-fread( "data / Survey_results_public.csv")

次に、操作と結果の確認を容易にするために、数列の新しいdata.tableを作成します。data.tableは次の基本構文を使用していることに注意してください。 

mydt [i、j、by]

data.tableパッケージの概要では、これを「dtを取得し、iを使用して行をサブセット化または並べ替え、jを計算し、でグループ化する」と説明しています。iとjは、ベースRのブラケットの順序(行が最初、列が2番目)に似ていることに注意してください。したがって、iは行に対して行う操作(行番号または条件に基づいて行を選択する)用です。jは、列で行うことです(列を選択するか、計算から新しい列を作成します)。ただし、ベースRデータフレームよりも多くの内部data.tableブラケットを実行できることにも注意してください。また、「by」セクションはdata.tableの新機能です。

列を選択しているので、そのコードは「j」スポットに配置されます。つまり、「i」スポットを空のままにするには、角かっこで最初にコンマが必要です。

mydt [、j]

data.table列を選択します

data.tableについて私が気に入っていることの1つは、引用符で囲まれたまたは引用符で囲まれていない列を簡単に選択できることです。多くの場合、引用されていない方が便利です(これは通常、整然とした方法です)。ただし、quotedは、独自の関数内でdata.tableを使用している場合、またはコード内の別の場所で作成したベクトルを渡したい場合に役立ちます。

引用符で囲まれた列名の従来のベクトルを使用して、一般的なベースRの方法でdata.table列を選択できます。例えば: 

dt1 <-mydt [、c( "LanguageWorkedWith"、 "LanguageDesireNextYear"、

「OpenSourcer」、「CurrencySymbol」、「ConvertedComp」、

「愛好家」)]

あなたがそれらを使用したい場合は、未引用されたが、作成するリストの代わりに、ベクトルを、あなたが引用符で囲まれていない名前で渡すことができます。 

dt1 <-mydt [、list(LanguageWorkedWith、LanguageDesireNextYear、

OpenSourcer、CurrencySymbol、ConvertedComp、

愛好家)]

そして今、私たちは最初の特別なシンボルに到達します。入力する代わりにlist()、ドットを使用できます。

dt1 <-mydt [、。(LanguageWorkedWith、LanguageDesireNextYear、

OpenSourcer、CurrencySymbol、ConvertedComp、

愛好家)]

これ.()は、list()data.tableブラケット内のショートカットです。

既存の列名のベクトルを使用する場合はどうなりますか?ベクトルオブジェクト名をdata.tableブラケット内に配置しても機能しません。次のように、引用符で囲まれた列名を使用してベクトルを作成すると、次のようになります。 

mycols <-c( "LanguageWorkedWith"、 "LanguageDesireNextYear"、

「OpenSourcer」、「CurrencySymbol」、「ConvertedComp」、「Hobbyist」)

その場合、このコードは機能し ません。 

dt1 <-mydt [、mycols]

代わりに、.. ベクターオブジェクト名の前に(2つのドット)を配置する必要があります。

dt1 <-mydt [、.. mycols]

なぜ2つのドット?説明を読むまで、それは私にはちょっとランダムに思えました。Unixコマンドラインターミナルの2つのドットが、1つのディレクトリに移動するようなものだと考えてください。ここでは、data.tableブラケット内の環境からグローバル環境に1つの名前空間を移動しています。(それは本当に私がそれを覚えるのを助けます!)

data.table行をカウントします

次のシンボルへ。グループでカウントするには、data.tableの.N記号を使用でき.Nます。ここで、 は「行数」を表します。行の総数、または「by」セクションで集計する場合はグループごとの行数にすることができます。 

この式は、data.tableの行の総数を返します。 

mydt [、。N]

次の例では、1つの変数でグループ化された行数を計算します。調査対象の人々が趣味(Hobbyist変数)としてもコーディングしているかどうか。

mydt [、。N、愛好家]

# 戻り値:

愛好家N1:はい71257 2:いいえ17626

変数が1つしかない場合は、data.table括弧内でプレーン列名を使用できます。2つ以上の変数でグループ化する場合は、.記号を使用します。例えば:

mydt [、.N、。(Hobbyist、OpenSourcer)]

結果を高いものから低いものへと並べ替えるには、最初の括弧の後に2番目の括弧のセットを追加します。.N行の数によって順序がこのような何かを見ることができるように、シンボルは自動的に、N(あなたがしたい場合はもちろん、あなたがそれを名前を変更することができます)という名前の列を生成します。

mydt [、.N、。(Hobbyist、OpenSourcer)] [order(Hobbyist、-N)]

data.tableコードを学習するにつれて、段階的に読むことが役立つと思います。したがって、これを「mydtのすべての行について(「I」スポットには何もないため)、行数を数え、HobbyistとOpenSourcerでグループ化する」と読みます。次に、最初に愛好家の順に並べ、次に行数を降順に並べます。」 

これは、このdplyrコードと同等です。

mydf%>%

count(Hobbyist、OpenSourcer)%>%

注文(愛好家、-n)

整頓された従来の複数行アプローチがより読みやすい場合は、このdata.tableコードも機能します。

mydt [、。N、

。(愛好家、OpenSourcer)] [

注文(愛好家、-N)

]

data.tableに列を追加します

次に、列を追加して、各回答者がRを使用しているか、Pythonを使用しているか、両方を使用しているか、またはどちらも使用していないかを確認します。このLanguageWorkedWith列には、使用されている言語に関する情報があり、そのデータのいくつかの行は次のようになります。

シャロン・マクリス

各回答は1文字の文字列です。ほとんどの言語には、セミコロンで区切られた複数の言語があります。

よくあることですが、「Python」を検索する方法で文字列内の「R」を検索することはできないため(RubyとRustには大文字のRも含まれます)、RよりもPythonを検索する方が簡単です。これは、の各文字列にLanguageWorkedWithPythonが含まれているかどうかをチェックするTRUE / FALSEベクトルを作成するためのより簡単なコードです。

ifelse(LanguageWorkedWith%like% "Python"、TRUE、FALSE)

SQLを知っている場合は、その「いいね」構文に気付くでしょう。私は、%like%. パターンマッチングをチェックするための優れた合理化された方法です。関数のドキュメントには、data.tableブラケット内で使用することを意図していると記載されていますが、実際には、data.tablesだけでなく、任意のコードで使用できます。data.tableの作成者であるMattDowleに確認しました。彼は、括弧内で使用することをお勧めするのは、そこでパフォーマンスの最適化が行われるためです。

次に、PythonUserという列をdata.tableに追加するコードを次に示します。

dt1 [、PythonUser:= ifelse(LanguageWorkedWith%like% "Python"、TRUE、FALSE)]

:=オペレーターに注意してください。Pythonにもそのような演算子があり、「セイウチ演算子」と呼ばれるのを聞いて以来、それを私は呼んでいます。正式には「参照による割り当て」だと思います。-上記のコードは、新しい列を追加することによって、data.table DT1既存のオブジェクトを変更しているためですなしで新しい変数に保存する必要が

Rを検索するには、次のような正規表現"\\bR\\b"を使用します。「単語の境界で始まり \\b、次に、、そしてR別の単語の境界で終わるパターンを見つけます。(各文字列の最後の項目にセミコロンがないため、「R;」だけを探すことはできません。) 

これにより、RUser列がdt1に追加されます。

dt1 [、RUser:= ifelse(LanguageWorkedWith%like% "\\ bR \\ b"、TRUE、FALSE)]

両方の列を一度に追加する:=場合は、次のように、そのwalrus演算子をバッククォートして関数に変換する必要があります。

dt1 [、`:=`

PythonUser = ifelse(LanguageWorkedWith%like% "Python"、TRUE、FALSE)、

RUser = ifelse(LanguageWorkedWith%like% "\\ bR \\ b"、TRUE、FALSE)

)]

より便利なdata.table演算子

知っておく価値のある他のいくつかのdata.table演算子があります。 %between% 演算子の構文は次のとおりです。

myvector%between%c(lower_value、upper_value)

したがって、補償が50,000〜100,000米ドルで支払われたすべての応答をフィルタリングする場合、このコードは機能します。

comp_50_100k <-dt1 [CurrencySymbol == "USD"&

ConvertedComp%between%c(50000、100000)]

上記の2行目は、between条件です。%between%演算子は、チェック時に下限値と上限値の両方を含めることに注意してください。

もう1つの便利な演算子は%chin%です。ベースRのように機能し%in%ますが、速度が最適化されており、文字ベクトル専用です。したがって、OpenSourcer列が「なし」または「1年に1回未満」のいずれかであるすべての行をフィルタリングする場合、このコードは機能します。

レアロス<-dt1 [OpenSourcer%chin%c( "Never"、 "Less than once year")]

これはベースRと非常に似ていますが、ベースRは角かっこ内にデータフレーム名を指定する必要があり、フィルター式の後にコンマも必要です。

rareos_df <-df1 [df1 $ OpenSourcer%in%c( "Never"、 "1年に1回未満")、]

新しいfcase()関数

この最後のデモでは、米ドルで報酬を報告した人だけで新しいdata.tableを作成することから始めます。

usd <-dt1 [CurrencySymbol == "USD"&!is.na(ConvertedComp)]

次に、Language誰かがRだけを使用するか、Pythonだけを使用するか、両方を使用するか、またはどちらも使用しないかを示す新しい列を作成します。そして、新しいfcase()関数を使用します。この記事が公開された時点でfcase()は、data.tableの開発バージョンでのみ利用可能でした。すでにdata.tableがインストールされている場合は、次のコマンドを使用して最新の開発バージョンに更新できます。 

data.table :: update.dev.pkg()

fcase()関数は、SQLのCASE WHENステートメントおよびdplyrのcase_when()関数に似ています。基本的な構文は次のとおりです fcase(condition1, "value1", condition2, "value2")。「その他すべて」のデフォルト値は、で追加できますdefault = value

新しい言語列を作成するコードは次のとおりです。

usd [、言語:= fcase(

RUser&!PythonUser、 "R"、

PythonUser&!RUser、 "Python"、

PythonUser&RUser、「両方」、

!PythonUser&!RUser、「どちらでもない」

)]

読みやすいので、各条件を別々の行に配置しましたが、必ずしもそうする必要はありません。

注意:RStudioを使用している場合、walrus演算子を使用して新しい列を作成した後、data.table構造は右上のRStudioペインで自動的に更新されません。列数の変化を確認するには、更新アイコンを手動でクリックする必要があります。

この記事で取り上げない記号は他にもいくつかあります。それらのリストは、を実行して「特殊記号」data.tableヘルプファイルにありますhelp("special-symbols")。最も便利な.SDの1つには、独自のDo More WithRの記事とビデオ「Rdata.tableパッケージで.SDを使用する方法」がすでにあります。

Rに関するその他のヒントについては、の「Do More With R」ページにアクセスするか、「Do MoreWithR」YouTubeプレイリストをご覧ください。