3 Oracle Machine Learning for Rスタート・ガイド

Oracle Machine Learning NotebooksでOML4Rを使用する方法について学習します。

3.1 Oracle Autonomous DatabaseでのOML4Rの使用

OML4Rは、Oracle Autonomous DatabaseでOracle Machine Learning NotebooksのRインタプリタを介して使用できます。

ノート:

OML4Rへの接続は、OML Notebooksを介して自動的に行われます。明示的な接続は必要ない、またはOML Notebooksで許可されていません。

詳細は、Oracle Machine Learning Notebooksの使用データ分析およびデータ視覚化のためのNotebooksスタート・ガイドを参照してください。

3.2 オンプレミスOracle DatabaseでのOML4Rの使用

Oracle Machine Learning for Rを使用するには、最初にOracle Databaseインスタンスに接続します。

3.2.1 データベースへの接続について

Oracle Machine Learning for Rクライアント・コンポーネントによって、RセッションがOracle DatabaseインスタンスおよびOML4Rサーバー・コンポーネントに接続されます。

この接続によってRユーザーはデータベース・スキーマ内のデータを使用できます。さらに、データベース・サーバーの処理能力、メモリーおよび記憶域容量を、OML4Rクライアント・インタフェースを介してRセッションで使用できるようになります。

次の各トピックでは、Oracle Databaseインスタンスに対するRセッションの接続および切断について説明します。

3.2.1.1 ore.connect関数の使用について

OML4Rの使用を開始するには、最初にore.connect関数を使用してOracle Databaseインスタンスのスキーマに接続します。

Rセッション中に同時に存在できるのは、1つのOML4R接続のみです。Rセッションがすでにデータベースに接続されている場合にore.connectを呼び出すと、アクティブな接続を終了してから新しい接続を開きます。接続を試みる前に、ore.is.connected関数を使用してアクティブな接続が存在するかどうかを確認できます。

ore.disconnect関数を使用して明示的に接続を終了します。ore.disconnectを呼び出さない場合は、Rセッションの終了時に接続が自動的に終了されます。

接続タイプORACLEを使用して、次を実行できます。

  • 論理引数allを使用して、OML4Rがスキーマ内でユーザーがアクセス権を持つ各表に対してore.frameオブジェクトを自動的に作成し、作成したore.frameオブジェクトを現在のRセッションで表示するかどうかを指定します。ore.frameオブジェクトには表に関するメタデータが含まれます。all引数のデフォルト値はFALSEです。

    all = TRUEの場合、OML4Rore.sync関数およびore.attach関数を暗黙的に呼び出します。all = FALSEの場合、ユーザーはore.syncを明示的に呼び出してore.frameオブジェクトを作成する必要があります。これらのオブジェクトに名前でアクセスするには、ユーザーはore.attachを呼び出して、検索パスにその名前を含める必要があります。

  • conn_string引数、またはusersidhostpasswordportservice_nameおよびconn_stringの引数の様々な組合せを使用して、接続を特定する情報を指定します。

    クリアテキスト・パスワードを使用しないようにするには、conn_string引数を使用してOracleウォレットのパスワードを指定できます。その他の引数は必要ありません。Oracleウォレットのパスワードを指定することで、アプリケーション・コード、バッチ・ジョブまたはスクリプトへのデータベース・ユーザーのパスワードの埋込みを避けることができます。

    その他の接続識別子の引数を使用する場合は、データベース・ユーザー名、ホスト名およびパスワード、システム識別子(SID)またはサービス名のいずれか、さらにオプションでTCPポートを指定するか、データベース・ユーザー名、パスワードおよびconn_string引数を指定します。

    port引数のデフォルト値は1521、hostのデフォルト値はlocalhost (ローカル・ホストを指定します)、conn_stringのデフォルト値はNULLです。接続するOracle Databaseインスタンスと同じコンピュータ上でRセッションを実行している場合は、ローカル・ホストを指定します。

3.2.1.2 ore.disconnect関数の使用について

RセッションとOracle Databaseインスタンス間の接続を明示的に終了するには、ore.disconnect関数を呼び出します。

次のいずれかを実行した場合、OML4Rore.disconnectを暗黙的に呼び出します。

  • Rセッションの終了

  • OML4R接続がすでにアクティブな場合のore.connectの呼出し。

アクティブな接続を切断すると、OML4Rは、OML4Rデータストアに明示的に保存されていないすべてのOML4Rオブジェクトを破棄します。

3.2.2 ore.connect関数およびore.disconnect関数の使用

この項の例では、Oracle DatabaseインスタンスへのOML4Rの接続を指定する様々な方法を示します。

各例では、ore.connect引数の値に、サンプルの値を使用しています。サンプルの値は、使用しているデータベースへの接続に適した値に置き換えてください。

例3-1 ore.connectの使用方法およびSIDの指定

この例では、ore.connect関数を呼び出し、usersidhostpasswordおよびport引数を指定します。

ore.connect(user = "oml_user", sid = "sales", host = "sales-server",
            password = "oml_userStrongPassword", port = 1521 )

例3-2 ore.connectの使用方法およびサービス名の指定

この例では、SIDのかわりにサービス名を使用する方法を示します。さらに、ローカル・ホストへの接続も指定します。

ore.connect(user = "oml_user", host = "localhost", 
            password = "oml_userStrongPassword",
            service_name = "sales.example.com")

例3-3 ore.connectの使用方法および簡単な接続文字列の指定

この例では、conn_string引数を使用して、接続を特定する簡単な接続文字列を指定します。

ore.connect(user = "oml_user", password = "oml_userStrongPassword", 
            conn_string = "sales-server:1521:sales
              (ADDRESS=(PROTOCOL=tcp) (HOST=sales-server) (PORT=1521))
              (CONNECT_DATA=(SERVICE_NAME=sales.example.com)))")

例3-4 ore.connectの使用方法および完全な接続文字列の指定

この例では、conn_string引数を使用して、接続を特定する完全な接続文字列を指定します。

ore.connect(user = "oml_user", password = "oml_userStrongPassword", 
            conn_string = "DESCRIPTION=
              (ADDRESS=(PROTOCOL=tcp) (HOST=sales-server) (PORT=1521))
              (CONNECT_DATA=(SERVICE_NAME=myserver.example.com))")

例3-5 conn_string引数を使用したOracle Walletの指定

この例では、conn_string引数を使用して、Oracleウォレットを指定します。mydb_test文字列は、Oracleデータベースの接続識別子です。Oracleウォレットには、接続を確立するために必要な情報が格納されています。OML4R接続のOracleウォレットを作成する方法の詳細は、『Oracle Machine Learning for Rインストレーションおよび管理ガイド』を参照してください。

ore.connect(conn_string = "mydb_test")

例3-6 conn_string引数の使用方法および空の接続文字列の指定

この例では、空の接続文字列を使用してローカル・ホストに接続します。

ore.connect(user = "oml_user", password = "oml_userStrongPassword", conn_string = "")

例3-7 プラガブル・データベースへの接続でのconn_string引数の使用方法

この例では、conn_string引数を使用してサービス名を指定して、プラガブル・データベースに接続します。

ore.connect(conn_string = "pdb1.example.com")

例3-8 プラガブル・データベースへの接続でのservice_name引数の使用方法

この例では、サービス名、ホスト名およびポート番号を使用してore.connectを呼び出し、プラガブル・データベースに接続します。

ore.connect(service_name = "pdb1.example.com", host = "mypdb", port = 1521)

例3-9 OML4Rセッションの切断

この例では、OML4RセッションをOracleデータベースから明示的に切断します。

ore.disconnect()

3.2.3 Oracle DatabaseでのRオブジェクトの作成および管理

透過層関数を使用すると、Oracle Databaseインスタンスに接続してデータベース・スキーマ内のデータ表およびビューと相互作用できます。

データベースに対してデータを移動でき、データベースの表およびビューを作成できます。さらに、Rオブジェクトをデータベースに保存できます。これらのアクションを実行するOML4Rの関数については、次の各項で説明します。

3.2.3.1 データベース・データのためのプロキシ・オブジェクトの使用

Oracle Machine Learning for Rを使用すると、RセッションでRプロキシ・オブジェクトを作成し、データベース表およびビューにアクセスして操作できます。

プロキシ・オブジェクトの作成については、次の各トピックで説明します。

3.2.3.1.1 データベース・オブジェクト用Rプロキシ・オブジェクトの作成について

データベース表およびビューへのアクセスおよび操作を可能にするプロキシ・オブジェクトを作成するには、ore.sync関数を使用します。

Rセッションでore.connectを呼び出すと、Oracle Machine Learning for RはOracle Databaseインスタンス内のスキーマへの接続を作成します。ore.sync関数は、スキーマ内の表のプロキシであるore.frameオブジェクトを作成します。ore.attach関数を使用して、R検索パスのスキーマを表すR環境を追加できます。

ore.sync関数を使用して、データベース表のプロキシとしてore.frameオブジェクトを作成する場合、ore.frameプロキシ・オブジェクトの名前はデータベース・オブジェクトの名前と同じです。各ore.frameプロキシ・オブジェクトには、対応するデータベース・オブジェクトに関するメタデータが含まれます。

このプロキシore.frameオブジェクトを使用して、表からデータを選択できます。表からデータを選択するR操作を実行すると、操作によってデータベース・オブジェクトから現在のデータが返されます。ただし、一部のアプリケーションが表に列を追加したか、データベース・オブジェクトのメタデータを変更した場合、そのデータベース・オブジェクトに対して再びore.syncが呼び出されるまでore.frameプロキシ・オブジェクトは変更を反映しません。

表を指定せずにore.sync関数を呼び出した場合、およびOracle Databaseインスタンスへの接続を確立したore.connect関数呼出しでall引数がFALSEだった場合は、ore.sync関数がore.connectに指定されたスキーマ内の各表にプロキシ・オブジェクトを作成します。table引数を使用してore.frameプロキシ・オブジェクトを作成する表を指定できます。

ヒント:

メモリー・リソースおよび時間を節約するには、Rセッションで使用する表にプロキシのみを追加してください。

schema引数を使用して、R環境およびプロキシ・オブジェクトを作成するスキーマを指定できます。指定したデータベース・スキーマに一度に存在できるのは、1つの環境のみです。use.keys引数を使用すると、ore.frameオブジェクトを順序付けするために表で主キーを使用するかどうかを指定できます。

ヒント:

順序付け、つまり順序を設定するためにデータの並べ替えを要求すると、一般的にコストが高くなり、必要でないかぎり回避する必要があります。Rでのほとんどの操作には順序付けは不要なため、データのサンプリングやその他の目的で必要な場合を除いて、通常はuse.keysFALSEに設定してください。

query引数を使用すると、SQL SELECT文を指定できます。これによって、データベース内にビューを作成せずに問合せ用のore.frameを作成できます。これは、現行スキーマに対してCREATE VIEWシステム権限を持っていない場合に有用です。schema引数とquery引数を同じore.sync呼出しで使用することはできません。

ore.ls関数を使用して、スキーマの環境内のデータベース表に対応するore.frameプロキシ・オブジェクトをリストできます。ore.exists関数を使用して、データベース表のore.frameプロキシ・オブジェクトがR環境に存在するかどうかを確認できます。プロキシ・オブジェクトが存在する場合はTRUEが、存在しない場合はFALSEが関数によって返されます。ore.rm関数を使用してR環境からore.frameプロキシ・オブジェクトを削除できます。

3.2.3.1.2 ore.sync関数を使用してプロキシ・オブジェクトを取得する例

次の例では、ore.sync関数の使用方法を示します。

この例ではまず、ore.exec関数を呼び出して、OML_USERデータベース・スキーマに存在する表を表すいくつかの表を作成します。次に、ore.syncを呼び出し、スキーマの3つの表を指定します。ore.syncの呼出しによりOML_USERスキーマにR環境を作成し、そのスキーマ内の指定された表に対するプロキシore.frameオブジェクトを作成します。この例では、現在の環境にあるore.frameプロキシ・オブジェクトをリストします。TABLE3表はスキーマ内に存在しますが、ore.frameプロキシ・オブジェクトは含まれません(このプロキシ・オブジェクトはore.sync呼出しに含められていないため)。

次に、query引数を使用してore.syncを呼び出して、指定されたSQL問合せに対するore.frameオブジェクトを作成します。再びore.frameオブジェクトをリストします。

次にore.syncを再び呼び出し、SHスキーマにR環境を作成し、そのスキーマ内の指定された表に対するプロキシ・オブジェクトをその環境内に作成します。この例では、ore.exists関数を呼び出して、指定された表が現在の環境に存在するかどうかを確認した後に、SH環境に存在するかどうかを確認します。SH環境内のRオブジェクトをリストします。

次に、ore.frameオブジェクトのQUERY1QUERY2およびTABLE4をOML_USER環境から削除します。最後に、環境内のプロキシ・オブジェクトを再びリストします。

ノート:

ore.rm関数の呼出しにより、TABLE4表のプロキシであるore.frameが環境から削除されます。スキーマから表は削除されません。

例3-10 ore.frameプロキシ・オブジェクトをR環境に追加するためのore.syncの使用方法

# After connecting to a database as OML_USER, create some tables.
ore.exec("CREATE TABLE TABLE1 AS SELECT * FROM dual")
ore.exec("CREATE TABLE TABLE2 AS SELECT * FROM dual")
ore.exec("CREATE TABLE TABLE3 AS SELECT * FROM dual")
ore.exec("CREATE TABLE TABLE4 AS SELECT * FROM dual")
# Create ore.frame objects for the specified tables.
ore.sync(table = c("TABLE1", "TABLE3", "TABLE4"))
# List the ore.frame proxy objects in the current environment.
ore.ls()
# Create ore.frame objects for the specified queries.
ore.sync(query = c("QUERY1" = "SELECT 0 X, 1 Y FROM dual",
                   "QUERY2" = "SELECT 1 X, 0 Y FROM dual"))
ore.ls()
# The OML_USER user has been granted SELECT permission on the tables in the 
# SH schema.
ore.sync("SH", table = c("CUSTOMERS", "SALES"))
# Find out if the CUSTOMERS ore.frame exists in the OML_USER environment.
ore.exists("CUSTOMERS")
# Find out if it exists in the SH environment.
ore.exists("CUSTOMERS", schema = "SH")
# List the ore.frame proxy objects in the SH environment.
ore.ls("SH")
# Remove the ore.frame objects for the specified objects.
ore.rm(c("QUERY1", "QUERY2", "TABLE4"))
# List the ore.frame proxy objects in the current environment again.
ore.ls()
この例のリスト
R> # After connecting to a database as OML_USER, create some tables.
R> ore.exec("CREATE TABLE TABLE1 AS SELECT * FROM dual")
R> ore.exec("CREATE TABLE TABLE2 AS SELECT * FROM dual")
R> ore.exec("CREATE TABLE TABLE3 AS SELECT * FROM dual")
R> ore.exec("CREATE TABLE TABLE4 AS SELECT * FROM dual")
R> # Create ore.frame objects for the specified tables.
R> ore.sync(table = c("TABLE1", "TABLE3", "TABLE4"))
R> # List the ore.frame proxy objects in the current environment.
R> ore.ls()
 [1] "TABLE1"     "TABLE3"     "TABLE4"
R> # Create ore.frame objects for the specified queries.
R> ore.sync(query = c("QUERY1" = "SELECT 0 X, 1 Y FROM dual",
+                     "QUERY2" = "SELECT 1 X, 0 Y FROM dual"))
R> ore.ls()
 [1] "QUERY1"     "QUERY2"     "TABLE1"     "TABLE3"     "TABLE4"
R> # The OML_USER user has been granted SELECT permission on the tables in the 
R> # SH schema.
R> ore.sync("SH", table = c("CUSTOMERS", "SALES"))
R> # Find out if the CUSTOMERS ore.frame exists in the OML_USER environment.
R> ore.exists("CUSTOMERS")
[1] FALSE
R> # Find out if it exists in the SH environment.
R> ore.exists("CUSTOMERS", schema = "SH")
[1] TRUE
R> # List the ore.frame proxy objects in the SH environment.
R> ore.ls("SH")
[1] "CUSTOMERS" "SALES"
R> # Remove the ore.frame objects for the specified objects.
R> ore.rm(c("QUERY1", "QUERY2", "TABLE4"))
R> # List the ore.frame proxy objects in the current environment again.
R> ore.ls()
 [1] "TABLE1"     TABLE3"
3.2.3.1.3 ore.get関数を使用したRプロキシ・オブジェクトの取得

ore.syncを使用してR環境およびore.frameプロキシ・オブジェクトを作成した後、R環境からore.get関数を使用してRプロキシ・オブジェクトを名前を指定して取得できます。

SH_CUST <- ore.get(name = "CUSTOMERS", schema = "SH")のようにore.getを使用して、表のプロキシore.frameを取得し、それをRで変数に割り当てることができます。ore.frameはRグローバル環境に存在し、この環境は.GlobalEnvを使用して参照できるため、ls関数によって返されるリストに表示されます。また、このオブジェクトはRグローバル環境に存在するため、データベース・スキーマを表すR環境とは対照的に、ore.ls関数によってリストされません。

例3-11 データベース表を取得するためのore.getの使用方法

この例では、ore.sync関数を呼び出して、SHスキーマのCUSTOMERS表のプロキシであるore.frameオブジェクトを作成します。次に、そのプロキシ・オブジェクトのディメンションを取得します。

ore.sync(schema = "SH", table = "CUSTOMERS", use.keys = FALSE)
dim(ore.get(name = "CUSTOMERS", schema = "SH"))
例3-11のリスト
R> ore.sync(schema = "SH", table = "CUSTOMERS", use.keys = FALSE)
R> dim(ore.get(name = "CUSTOMERS", schema = "SH"))
[1] 630  15
3.2.3.1.4 ore.attach関数を使用したスキーマの追加

ore.attachを使用して、データベース・スキーマのR環境をR検索パスに追加します。

R環境を追加すると、スキーマ環境を指定することなくore.sync関数で作成したプロキシ・オブジェクトを介してデータベース表に名前を指定してアクセスできます。

デフォルト・スキーマは接続作成時に指定したもので、検索パスでのデフォルト位置は2です。スキーマおよび位置はore.attach関数呼出しで指定できます。また、環境の追加時に名前の競合が発生するかどうかをore.attach関数で示すかどうかを指定できます。ore.detach関数を使用して、R検索パスからスキーマに対する環境をデタッチできます。

例3-12 データベース・スキーマの環境を追加するためのore.attachの使用方法

この例では、ore.attach関数の使用方法を示します。例にあるコメントは、関数の呼出しを説明しています。

# Connected as oml_user.
# Add the environment for the oml_user schema to the R search path.
ore.attach()
# Create an unordered ore.frame proxy object in the SH environment for the
# specifed table.
ore.sync(schema = "SH", table = "CUSTOMERS", use.keys = FALSE)
# Add the environment for the SH schema to the search path and warn if naming
# conflicts exist.
ore.attach("SH", 3, warn.conflicts = TRUE)
# Display the number of rows and columns in the proxy object for the table.
dim(CUSTOMERS)
# Remove the environment for the SH schema from the search path.
ore.detach("SH")
# Invoke the dim function again.
dim(CUSTOMERS)
例3-12のリスト
R> # Connected as oml_user.
R> # Add the environment for the oml_user schema to the R search path.
R> ore.attach()
R> # Create an unordered ore.frame proxy object in the SH environment for the
R> # specifed table.
R> ore.sync(schema = "SH", table = "CUSTOMERS", use.keys = FALSE)
R> # Add the environment for the SH schema to the search path and warn if naming
R> # conflicts exist.
R> ore.attach("SH", 3, warn.conflicts = TRUE)
R> # Display the number of rows and columns in the proxy object for the table.
R> dim(CUSTOMERS)
[1] 630  15
R> # Remove the environment for the SH schema from the search path.
R> ore.detach("SH")
R> # Invoke the dim function again.
R> dim(CUSTOMERS)
Error: object 'CUSTOMERS' not found
3.2.3.2 データベース表の作成および削除

ore.create関数を使用して、Oracle Databaseスキーマの永続表を作成します。

ノート:

Oracle Machine Learning for Rで表を作成するときに表の名前に小文字または大/小文字の組合せを使用する場合、SQL問合せまたは関数で表を使用するときは、同じ小文字または大/小文字の組合せの名前を二重引用符で囲って使用する必要があります。表を作成するときにすべて大文字の名前を使用する場合、表の名前は大/小文字が区別されません。二重引用符を使用せずに表を使用する場合、大文字、小文字、または大文字/小文字の組合せを使用できます。これは、表の列に名前を付ける場合も同様です。

表を作成すると、データベース・スキーマを表すR環境に表のore.frameプロキシ・オブジェクトが自動的に作成されます。プロキシore.frameオブジェクトには表と同じ名前が付けられます。ore.drop関数を使用して、Oracle Databaseスキーマの永続表を削除できます。

注意:

ore.drop関数は、データベース表およびそれに関連付けられたore.frameプロキシ・オブジェクトを削除する場合にのみ使用します。永続データベース表と関連付けられてないore.frameオブジェクトを削除する場合は、これを使用しないでください。一時データベース表のore.frameオブジェクトを削除する場合は、ore.rm関数を使用します。

例3-13 表を作成および削除するためのore.createおよびore.dropの使用方法

この例では、データベース内に表を作成し、それらの一部を削除します。

# Create the AIRQUALITY table from the data.frame for the airquality data set.
ore.create(airquality, table = "AIRQUALITY")
# Create data.frame objects.
df1 <- data.frame(x1 = 1:5, y1 = letters[1:5])
df2 <- data.frame(x2 = 5:1, y2 = letters[11:15])
# Create the DF1 and DF2 tables from the data.frame objects.
ore.create(df1, "DF1")
ore.create(df2, "DF2")
# Create the CARS93 table from the data.frame for the Cars93 data set.
ore.create(Cars93, table = "CARS93")
# List the OML4R proxy objects.
ore.ls()
# Drop the CARS93 object.
ore.drop(table = "CARS93")
# List the OML4R proxy objects again.
ore.ls()

この例のリスト

R> # Create the AIRQUALITY table from the data.frame for the airquality data set.
R> ore.create(airquality, table = "AIRQUALITY")
R> # Create data.frame objects.
R> df1 <- data.frame(x1 = 1:5, y1 = letters[1:5])
R> df2 <- data.frame(x2 = 5:1, y2 = letters[11:15])
R> # Create the DF1_TABLE and DF2_TABLE tables from the data.frame objects.
R> ore.create(df1, "DF1")
R> ore.create(df2, "DF2")
R> # Create the CARS93 table from the data.frame for the Cars93 data set.
R> ore.create(Cars93, table = "CARS93")
R> # List the OML4R proxy objects.
R> ore.ls()
[1] "AIRQUALITY"  "CARS93"  "DF1"  "DF2_"
R> # Drop the CARS93 object.
R> ore.drop(table = "CARS93")
R> # List the OML4R proxy objects again.
R> ore.ls()
[1] "AIRQUALITY"  "DF1_"  "DF2"

ノート:

4000文字を超えるテキスト問合せ、または4000文字を超える値をCLOB列に格納すると、「ORA-01704: 文字列リテラルが長すぎます」というエラーが発生します。次に示すようにデータが大きい場合は、バインド変数を使用します。バインド変数の詳細は、ROracleを参照してください。

library(ROracle)
options(error = expression(NULL))
Sys.setlocale(‘LC_ALL’, ‘C’)
cat(‘\n Welcome to ROracle(OCI) World\n’);
cat(‘\n DBI Version : ’);
print(packageVersion(‘DBI’));
cat(‘\n’);
#Creating table whose fields are of different type
createStr <- ‘create table TMRQORABND1_TAB(row_num number, id1 clob)’;
insStr <- ‘insert into TMRQORABND1_TAB values(:1, :2)’;
selStr <- ‘select * from TMRQORABND1_TAB order by row_num’;
y <- ‘1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef’;
z <- y
z <- paste(y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, ‘1234567890abcdef1234567890abcdef’, sep = ‘’);
c32767 <- paste(z, z, z, z, z, z, z, z, y, y, y, y, y, y, y, y, y, y, y,
          ‘1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcde’,
          sep = ‘’)
print(nchar(c32767))
c32766 <- paste(z, z, z, z, z, z, z, z, y, y, y, y, y, y, y, y, y, y, y,
          ‘1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcd’,
          sep = ‘’)
print(nchar(c32766))
c32768 <- paste(z, z, z, z, z, z, z, z, y, y, y, y, y, y, y, y, y, y, y,
          ‘1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef’,
          sep = ‘’)
print(nchar(c32768))
y <- paste(y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, ‘1234567890abcdef1234567890abcdef’, sep = ‘’);
y1 <- y
y <- paste(y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, ‘1234567890abcdef1234567890abcdef’, sep = ‘’);
y2 <- y
y <- paste(y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
          y, y, ‘1234567890abcdef1234567890abcdef’, sep = ‘’);
y3 <- y
y4 <- paste(y3, y3, y3, y3, y3)
r1c2 <- paste(y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y, y,
             y, y, ‘1234567890abcdef1234567890abcdef’, sep = ‘’);
print(nchar(y));
drv <- dbDriver(‘Oracle’);
cat(‘\n ROracle driver allocated.\n’);
con <- dbConnect(drv,‘scott’,‘tiger’);
cat(‘\n One database connection object created.\n’);
#tryCatch(
#{
 if (dbExistsTable(con, ‘TMRQORABND1_TAB’))
   dbGetQuery(con,‘drop table TMRQORABND1_TAB’);
 dbGetQuery(con, createStr);
 cat(‘\nTable created with columns data type as raw(n) \n’);
 x <- 1;
 dbGetQuery(con, insStr, data.frame(x,r1c2));
 dbCommit(con);
 x <- c(2, 3, 4, 5, 6, 7, 8, 9, 10);
 yy <- c(y1, y2, y3, z, y4, c32767, c32766, c32768, ‘’);
 dbGetQuery(con, insStr, data.frame(x, yy));
 dbCommit(con)
 print(dbGetQuery(con, ‘select row_num, length(id1) from TMRQORABND1_TAB’));
 x <- 100;
 y <- paste(y, c32767, sep = ‘’);
 dbGetQuery(con, insStr, data.frame(x,y));
 dbCommit(con)
 s <- dbSendQuery(con, selStr)
 cinfo <- dbColumnInfo(s)
 print(dbGetQuery(con, ‘select row_num, length(id1) from TMRQORABND1_TAB’));
 res <- dbGetQuery(con, selStr)
 if (res[,2][1] != r1c2) {
   print(paste(‘Row’, res[,1][1], cinfo[,1][2], res[,2][1],
               ‘not equal to’, r1c2))
 } else {
   print(paste(‘Row’, res[,1][1], cinfo[,1][2], ‘length is’,
               nchar(res[,2][1]),
               ‘length of data is’, nchar(r1c2)), sep = ‘’)
 }
 for (i in 2:9)
 {
   if (res[,2][i] != yy[i-1]) {
     print(paste(‘Row’, res[,1][i], cinfo[,1][2], res[,2][i],
                 ‘not equal to’, yy[i-1]))
   } else {
     print(paste(‘Row’, res[,1][i], cinfo[,1][2], ‘length is’,
                 nchar(res[,2][i]),
                 ‘length of data is’, nchar(yy[i-1])), sep = ‘’)
   }
 }
 if (!is.na(res[,2][10])) {
   print(paste(‘Row’, res[,1][10], cinfo[,1][2], res[,2][10],
               ‘not equal to’, yy[9]))
 } else {
   print(paste(‘Row’, res[,1][10], cinfo[,1][2], ‘length is’,
               nchar(res[,2][10]),
               ‘length of data is’, nchar(yy[9])), sep = ‘’)
 }
 if (res[,2][11] != y) {
   print(paste(‘Row’, res[,1][11], cinfo[,1][2], res[,2][11],
               ‘not equal to’, y))
 } else {
   print(paste(‘Row’, res[,1][11], cinfo[,1][2], ‘length is’,
               nchar(res[,2][11]),
               ‘length of data is’, nchar(y)), sep = ‘’)
 }
#}, finally = {
 dbGetQuery(con,‘drop table TMRQORABND1_TAB’);
 cat(‘\n ROracle driver deallocated successfully.\n’);
 cat(‘Releasing resources...‘);
 dbDisconnect(con);
 cat(‘\n Connection with database removed successfully.\n’);
 dbUnloadDriver(drv);
 cat(‘done\n’);
#}) # tryCatch()
3.2.3.3 一時データベース表の作成

ore.push関数を使用して、ローカルR data.frameオブジェクトから一時データベース表およびそれに対応するプロキシore.frameオブジェクトを作成できます。

ore.pull関数を使用して、OML4Rプロキシ・オブジェクトが表すデータのコピーを含むローカルのRオブジェクトを作成できます。

ore.push関数は、Rオブジェクトを適切なデータ型のOML4Rオブジェクトに変換します。ore.pull関数は、oreクラス・オブジェクトを取得してRオブジェクトを返します。入力オブジェクトがore.listの場合、ore.pull関数はdata.frameを作成し、各データベース列のデータを適切なR表現に変換します。

ノート:

データがRセッション・メモリーに適合する場合にのみ、データをローカルRのdata.frameにプルできます。また、データがメモリーに適合しても非常に大きい場合は、多数の、またはすべてのR関数をクライアントRセッションで実行できない可能性があります。

ore.push関数を使用して作成されたデータベースのデータストアにプロキシ・オブジェクトを明示的に保存しないかぎり、Rセッションの終了時に一時表およびプロキシ・オブジェクトは破棄されます。

例3-14 データを移動するためのore.pushおよびore.pullの使用方法

この例は、Rのdata.frameオブジェクトを関連するore.frameオブジェクト(iris_of)とともに一時データベース表としてデータベースにプッシュし、iris_ofから1列を選択することによって別のore.frameオブジェクト(iris_of_setosa)を作成した後に、iris_of_setosaオブジェクトをdata.frameオブジェクトとしてローカルのRセッション・メモリーにプルすることを示します。この例では、一部のオブジェクトのクラスを表示します。

class(iris)
# Push the iris data frame to the database.
iris_of <- ore.push(iris)
class(iris_of)
# Display the data type of the Sepal.Length column in the data.frame.
class(iris$Sepal.Length)
# Display the data type of the Sepal.Length column in the ore.frame.
class(iris_of$Sepal.Length)
# Filter one column of the data set.
iris_of_setosa <- iris_of[iris_of$Species == "setosa", ]
class(iris_of_setosa)
# Pull the selected column into the local R memory.
local_setosa = ore.pull(iris_of_setosa)
class(local_setosa)
この例のリスト
R> class(iris)
[1] "data.frame"
R> # Push the iris data frame to the database.
R> iris_of <- ore.push(iris)
R> class(iris_of)
[1] "ore.frame"
attr(,"package")
[1] "OREbase"
R> # Display the data type of the Sepal.Length column in the data.frame.
R> class(iris$Sepal.Length)
[1] "numeric"
R> # Display the data type of the Sepal.Length column in the ore.frame.
R> class(iris_of$Sepal.Length)
[1] "ore.numeric"
attr(,"package")
[1] "OREbase"
R> # Filter one column of the data set.
R> iris_of_setosa <- iris_of[iris_of$Species == "setosa", ]
R> class(iris_of_setosa)
[1] "ore.frame"
attr(,"package")
[1] "OREbase"
R> # Pull the selected column into the local R memory.
R> local_setosa = ore.pull(iris_of_setosa)
R> class(local_setosa)
[1] "data.frame"
3.2.3.4 順序付けられたおよび順序付けられていないore.frameオブジェクトの作成

Oracle Machine Learning for Rでは、順序付けられたまたは順序付けられていないore.frameオブジェクトを作成できます。

次の各項目でこの機能について説明します。

3.2.3.4.1 ore.frameオブジェクトの順序付けについて

vectordata.frameなどのRオブジェクトには、その要素の暗黙的な順序付けがあります。

Oracle Database表のデータは、必ずしも順序付けられている必要はありません。一部のR操作では順序付けは役立ちますが、他の操作では必要ではありません。ore.frameを順序付けすることで、整数または文字列索引のいずれかを使用してore.frameオブジェクトに索引付けできます。

SQL問合せに対するプロキシである順序付けられたore.frameオブジェクトを使用すると、大規模なデータセットでは時間がかかります。そのため、OML4Rはデフォルトで順序付けられたore.frameオブジェクトの作成を試みますが、順序付けられていないore.frameオブジェクトを作成するための方法も提供されています。

ore.sync関数を呼び出して、SQL問合せのプロキシとしてOML4Rore.frameオブジェクトを作成する場合、use.keys引数を使用してore.frameを順序付けするか、しないようにするかを指定できます。

次の1つ以上の条件を満たす場合、ore.frameオブジェクトは順序付けられます。

  • ore.sync関数のuse.keys引数の値がTRUEで、基礎となる表で主キーが定義されている

  • ore.frameの行名が一意のタプルを構成する

  • ore.frameオブジェクトがaggregatecbindなどの特定の関数で生成されている

  • 関連するOML4Rの関数に対する入力引数であるore.frameオブジェクトのすべてが順序付けられている

次の1つ以上の条件を満たす場合、ore.frameオブジェクトは順序付けられません。

  • ore.sync関数のuse.keys引数の値がFALSEである

  • 主キーが基礎となる表に定義されておらず、ore.frameオブジェクトの行名が指定されていないか、ore.frameオブジェクトの行名がNULLに設定されている

  • 関連するOML4Rの関数に対する入力引数である1つ以上のore.frameオブジェクトが順序付けられていない

順序付けられていないore.frameオブジェクトにはNULLの行名があります。例3-15の最後の行に示すように、オブジェクトの行名でis.nullを呼び出すことによってore.frameオブジェクトが順序付けられるかどうかを判断できます。ore.frameオブジェクトが順序付けられていない場合、is.nullはエラーを返します。

3.2.3.4.2 順序付けに関連するグローバル・オプション

OML4Rには、ore.frameオブジェクトの順序付けに関連するオプションがあります。

ore.warn.orderグローバル・オプションは、順序付けが必要な関数で順序付けられていないore.frameオブジェクトを使用した場合にOML4Rが警告メッセージを表示するかどうかを指定します。操作で期待される内容がわかっている場合は、出力に表示されないように警告を無効化する必要がある場合があります。警告メッセージの例は、例3-15および例3-16を参照してください。

次の例に示すとおり、現在の設定を確認したり、このオプションを有効化または無効化できます。

R> options("ore.warn.order")
$ore.warn.order
[1] TRUE
R> options("ore.warn.order" = FALSE)
R> options("ore.warn.order" = TRUE)

ore.sepオプションを使用すると、次の例に示すとおり、複数列キーに使用する行名の値の間にセパレータを指定できます。

R> options("ore.sep")
$ore.sep
[1] "|"

R> options("ore.sep" = "/")
R> options("ore.sep" = "|")
3.2.3.4.3 キーを使用した順序付け

データベース表の主キーを使用して、ore.frameオブジェクトを順序付けします。

次の例では、スパム・データセットをkernlabパッケージからロードします。2つの列をデータセットに追加します。

この例では、ore.dropを呼び出して、指定された表(存在する場合)を削除します。次に、ore.createを呼び出して、データセットから2つの表を作成します。ore.execを呼び出して、USERID列とTS列をSPAM_PK表の複合主キーにし、ore.syncを呼び出して、表をそのore.frameプロキシと同期します。

ノート:

ore.exec関数は、Oracle DatabaseスキーマでSQL文を実行します。この関数は、戻り値を持たないデータベース定義言語(DDL)文を対象としています。

例ではその後、各表の最初の8行を表示します。SPAM_PK表のプロキシ・オブジェクトは、順序付けられたore.frameオブジェクトです。これには、"|"文字で区切られたTS列とUSERID列の値を組み合せた行名が含まれます。SPAM_NOPK表のプロキシ・オブジェクトは順序付けられていないore.frameオブジェクトで、これには記号SPAM_NOPKが付けられます。デフォルトで、SPAM_NOPKには連番の行名が付けられます。

例3-15 キーを使用した順序付け

# Prepare the data.
library(kernlab)
data(spam)
s <- spam
# Create a column that has integer values.
s$TS <- 1001:(1000 + nrow(s))
# Create a column that has integer values with each number repeated twice.
s$USERID <- rep(351:400, each=2, len=nrow(s))
# Ensure that the database tables do not exist.
ore.drop(table='SPAM_PK')
ore.drop(table='SPAM_NOPK')
# Create database tables.
ore.create(s[,c(59:60,1:28)], table="SPAM_PK")
ore.create(s[,c(59:60,1:28)], table="SPAM_NOPK")
# Using a SQL statement, alter the SPAM_PK table to add a composite primary key.
ore.exec("alter table SPAM_PK add constraint SPAM_PK primary key
           (\"USERID\",\"TS\")")
# Synchronize the table to get the change to it.
ore.sync(table = "SPAM_PK")
# View the data in the tables.
# The row names of the ordered SPAM_PK are the primary key column values.
head(SPAM_PK[,1:8])
# The row names of the unordered SPAM_NOPK are sequential numbers.
# The first warning results from the inner accessing of SPAM_NOPK to subset
# the columns. The second warning is for the invocation of the head
# function on that subset.
head(SPAM_NOPK[,1:8])
# Verify that SPAM_NOPK is unordered.
is.null(row.names(SPAM_NOPK))
この例のリスト
R> # Prepare the data.
R> library(kernlab)
R> data(spam)
R> s <- spam
R> # Create a column that has integer values.
R> s$TS <- 1001:(1000 + nrow(s))
R> # Create a column that has integer values with each number repeated twice.
R> s$USERID <- rep(351:400, each=2, len=nrow(s))
R> # Ensure that the database tables do not exist.
R> ore.drop(table='SPAM_PK')
R> ore.drop(table='SPAM_NOPK')
R> # Create database tables.
R> ore.create(s[,c(59:60,1:28)], table="SPAM_PK")
R> ore.create(s[,c(59:60,1:28)], table="SPAM_NOPK")
R> # Using a SQL statement, alter the SPAM_PK table to add a composite primary key.
R> ore.exec("alter table SPAM_PK add constraint SPAM_PK primary key
+  (\"USERID\",\"TS\")")
R> # Synchronize the table to get the change to it.
R> ore.sync(table = "SPAM_PK")
R> # View the data in the tables.
R> # The row names of the ordered SPAM_PK are the primary key column values.
R> head(SPAM_PK[,1:8])
           TS USERID make address  all num3d  our over
1001|351 1001    351 0.00    0.64 0.64     0 0.32 0.00
1002|351 1002    351 0.21    0.28 0.50     0 0.14 0.28
1003|352 1003    352 0.06    0.00 0.71     0 1.23 0.19
1004|352 1004    352 0.00    0.00 0.00     0 0.63 0.00
1005|353 1005    353 0.00    0.00 0.00     0 0.63 0.00
1006|353 1006    353 0.00    0.00 0.00     0 1.85 0.00
R> # The row names of the unordered SPAM_NOPK are sequential numbers.
R> # The first warning results from the inner accessing of SPAM_NOPK to subset
R> # the columns. The second warning is for the invocation of the head
R> # function on that subset.
R> head(SPAM_NOPK[,1:8])
    TS USERID make address  all num3d  our over
1 1001    351 0.00    0.64 0.64     0 0.32 0.00
2 1002    351 0.21    0.28 0.50     0 0.14 0.28
3 1003    352 0.06    0.00 0.71     0 1.23 0.19
4 1004    352 0.00    0.00 0.00     0 0.63 0.00
5 1005    353 0.00    0.00 0.00     0 0.63 0.00
6 1006    353 0.00    0.00 0.00     0 1.85 0.00
Warning messages:
1: ORE object has no unique key - using random order 
2: ORE object has no unique key - using random order
R> # Verify that SPAM_NOPK is unordered.
R> is.null(row.names(SPAM_NOPK))
Error: ORE object has no unique key
3.2.3.4.4 行名を使用した順序付け

行名を使用してore.frameオブジェクトを順序付けできます。

次の例では、ローカルのRセッション・メモリーにdata.frameオブジェクトを作成し、それをore.frameオブジェクト(Rセッションが接続されているOracle Databaseのメモリーにあります)に記号aを付けてプッシュします。この例では、ore.frameオブジェクトにRのdata.frameオブジェクトのデフォルトの行名が付けられていることを示します。ore.frameが順序付けられているため、そこでrow.names関数を呼び出すと警告メッセージは生成されません。

この例では、ore.frameオブジェクトの順序付けられたSPAM_PKおよび順序付けられていないSPAM_NOPKを使用して、順序付けられていないSPAM_NOPKrow.namesを呼び出すと警告メッセージが生成されますが、順序付けられているSPAM_PKでは生成されないことを示します。

SPAM_PKオブジェクトは行名で順序付けられていて、この行名は|文字で区切られたTSとUSERID列値を組み合せた値です。この例では、行名を変更できることを示します。

例3-16 行名を使用した順序付け

# Prepare the data.
library(kernlab)
data(spam)
s <- spam
# Create a column that has integer values.
s$TS <- 1001:(1000 + nrow(s))
# Create a column that has integer values with each number repeated twice.
s$USERID <- rep(351:400, each=2, len=nrow(s))
# Ensure that the database tables do not exist.
ore.drop(table='SPAM_PK')
ore.drop(table='SPAM_NOPK')
# Create database tables.
ore.create(s[,c(59:60,1:28)], table="SPAM_PK")
ore.create(s[,c(59:60,1:28)], table="SPAM_NOPK")
# Using a SQL statement, alter the SPAM_PK table to add a composite primary key.
ore.exec("alter table SPAM_PK add constraint SPAM_PK primary key
           (\"USERID\",\"TS\")")
# Synchronize the table to get the change to it.
ore.sync(table = "SPAM_PK")
# Create an ordered ore.frame by default.
a <- ore.push(data.frame(a=c(1:10,10:1), b=letters[c(1:10,10:1)]))
# Display the values in the b column. Note that because the ore.frame is
# ordered, no warnings appear.
a$b
# Display the default row names for the first six rows of the a column.
row.names(head(a))
# SPAM_NOPK has no unique key, so row.names raises error messages.
row.names(head(SPAM_NOPK))
# Row names consist of TS ‘|' USERID.
# For display on this page, only the first four row names are shown.
row.names(head(SPAM_PK))
# Reassign the row names to the TS column only
row.names(SPAM_PK) <- SPAM_PK$TS
# The row names now correspond to the TS values only.
row.names(head(SPAM_PK[,1:4]))
head(SPAM_PK[,1:4])
この例のリスト
R> # Prepare the data.
R> library(kernlab)
R> data(spam)
R> s <- spam
R> # Create a column that has integer values.
R> s$TS <- 1001:(1000 + nrow(s))
R> # Create a column that has integer values with each number repeated twice.
R> s$USERID <- rep(351:400, each=2, len=nrow(s))
R> # Ensure that the database tables do not exist.
R> ore.drop(table='SPAM_PK')
R> ore.drop(table='SPAM_NOPK')
R> # Create database tables.
R> ore.create(s[,c(59:60,1:28)], table="SPAM_PK")
R> ore.create(s[,c(59:60,1:28)], table="SPAM_NOPK")
R> # Using a SQL statement, alter the SPAM_PK table to add a composite primary key.
R> ore.exec("alter table SPAM_PK add constraint SPAM_PK primary key
+  (\"USERID\",\"TS\")")
R> # Synchronize the table to get the change to it.
R> ore.sync(table = "SPAM_PK")
R> # Create an ordered ore.frame by default.
R> a <- ore.push(data.frame(a=c(1:10,10:1), b=letters[c(1:10,10:1)]))
R> # Display the values in the b column. Note that because the ore.frame is
R> # ordered, no warnings appear.
R> a$b
 [1] a b c d e f g h i j j i h g f e d c b aLevels: a b c d e f g h i j
R> # Display the default row names for the first six rows of the a column.
R> row.names(head(a))
[1] 1 2 3 4 5 6
R> # SPAM_NOPK has no unique key, so row.names raises error messages.
R> row.names(head(SPAM_NOPK))
Error: ORE object has no unique key
In addition: Warning message:
ORE object has no unique key - using random order
R> # Row names consist of TS ‘|' USERID.
R> # For display on this page, only the first four row names are shown.
R> row.names(head(SPAM_PK))
        1001|351         1002|351         1003|352         1004|352
"1001|3.51E+002" "1002|3.51E+002" "1003|3.52E+002" "1004|3.52E+002"
R> # Reassign the row names to the TS column only
R> row.names(SPAM_PK) <- SPAM_PK$TS
R> # The row names now correspond to the TS values only.
R> row.names(head(SPAM_PK[,1:4]))
[1] 1001 1002 1003 1004 1005 1006
R> head(SPAM_PK[,1:4])
       TS USERID make address
1001 1001    351 0.00    0.64
1002 1002    351 0.21    0.28
1003 1003    352 0.06    0.00
1004 1004    352 0.00    0.00
1005 1005    353 0.00    0.00
1006 1006    353 0.00    0.00
3.2.3.4.5 順序付けられたフレームの使用方法

この例では、順序付けられた2つのore.frameオブジェクトと順序付けられていない2つのore.frameオブジェクトをマージした結果を示します。

例3-17 順序付けられたおよび順序付けられていないore.frameオブジェクトのマージ

# Prepare the data.
library(kernlab)
data(spam)
s <- spam
# Create a column that has integer values.
s$TS <- 1001:(1000 + nrow(s))
# Create a column that has integer values with each number repeated twice.
s$USERID <- rep(351:400, each=2, len=nrow(s))
# Ensure that the database tables do not exist.
ore.drop(table='SPAM_PK')
ore.drop(table='SPAM_NOPK')
# Create database tables.
ore.create(s[,c(59:60,1:28)], table="SPAM_PK")
ore.create(s[,c(59:60,1:28)], table="SPAM_NOPK")
# Using a SQL statement, alter the SPAM_PK table to add a composite primary key.
ore.exec("alter table SPAM_PK add constraint SPAM_PK primary key
           (\"USERID\",\"TS\")")
# Synchronize the table to get the change to it.
ore.sync(table = "SPAM_PK")
# Create objects for merging data from unordered ore.frame objects.
x <- SPAM_NOPK[,1:4]
y <- SPAM_NOPK[,c(1,2,4,5)]
m1 <- merge(x, y, by="USERID")
# The merged result m1 produces a warning because it is not an ordered frame.
head(m1,3)
# Create objects for merging data from ordered ore.frame objects.
x <- SPAM_PK[,1:4]
y <- SPAM_PK[,c(1,2,4,5)]
# The merged result m1 does not produce a warning now because it is an 
# ordered frame.
m1 <- merge(x, y, by="USERID")
head(m1,3)
この例のリスト
R> # Prepare the data.
R> library(kernlab)
R> data(spam)
R> s <- spam
R> # Create a column that has integer values.
R> s$TS <- 1001:(1000 + nrow(s))
R> # Create a column that has integer values with each number repeated twice.
R> s$USERID <- rep(351:400, each=2, len=nrow(s))
R> # Ensure that the database tables do not exist.
R> ore.drop(table='SPAM_PK')
R> ore.drop(table='SPAM_NOPK')
R> # Create database tables.
R> ore.create(s[,c(59:60,1:28)], table="SPAM_PK")
R> ore.create(s[,c(59:60,1:28)], table="SPAM_NOPK")
R> # Uing a SQL statement, alter the SPAM_PK table to add a composite primary key.
R> ore.exec("alter table SPAM_PK add constraint SPAM_PK primary key
+          (\"USERID\",\"TS\")")
R> # Synchronize the table to get the change to it.
R> ore.sync(table = "SPAM_PK")
R> # Create objects for merging data from unordered ore.frame objects.
R> x <- SPAM_NOPK[,1:4]
R> y <- SPAM_NOPK[,c(1,2,4,5)]
R> m1 <- merge(x, y, by="USERID")
R> # The merged result m1 produces a warning because it is not an ordered frame.
R> head(m1,3)
  USERID TS.x make address.x TS.y address.y  all
1    351 5601 0.00         0 1001      0.64 0.64
2    351 5502 0.00         0 1001      0.64 0.64
3    351 5501 0.78         0 1001      0.64 0.64
Warning messages:
1: ORE object has no unique key - using random order 
2: ORE object has no unique key - using random order
R> # Create objects for merging data from ordered ore.frame objects.
R> x <- SPAM_PK[,1:4]
R> y <- SPAM_PK[,c(1,2,4,5)]
R> # The merged result m1 does not produce a warning now because it is an 
R> # ordered frame.
R> m1 <- merge(x, y, by="USERID")
R> head(m1,3)
          USERID TS.x make address.x TS.y address.y  all
1001|1001    351 1001    0      0.64 1001      0.64 0.64
1001|1002    351 1001    0      0.64 1002      0.28 0.50
1001|1101    351 1001    0      0.64 1101      0.00 0.00
3.2.3.5 データベースでのRオブジェクトの保存および管理

Oracle Machine Learning for Rには、OML4Rプロキシ・オブジェクトおよび任意のRオブジェクトをOracle Databaseに保存するために使用できるデータストアが用意されています。

1人以上のユーザーについてデータストアへの読取りアクセス権を付与したり、取り消すことができます。保存したオブジェクトを別のRセッションにリストアできます。データストアのオブジェクトは、RインタフェースとSQLインタフェースの両方を介してEmbedded R Executionからもアクセスできます。

この項では、データストアの作成および管理に使用可能なOML4Rの関数について説明します。この項の内容は次のとおりです。

3.2.3.5.1 Oracle Machine Learning for Rオブジェクトの永続化について

OML4Rのデータストアを使用すると、Rオブジェクトをデータベースに保存できます。

Rオブジェクト(OML4Rプロキシ・オブジェクトを含む)は、明示的に保存しないかぎり現行のRセッションの間存在します。Rオブジェクトの保存およびリストア用の標準のR関数(saveおよびload)は、ファイルに格納するためにRメモリー内のオブジェクトをシリアライズし、メモリーにリストアするためにデシリアライズします。ただし、OML4Rプロキシ・オブジェクトに対しては、それらの関数はプロキシ・オブジェクトに関連付けられているデータベース・オブジェクトをOracle Databaseに保存しないため、保存されたプロキシ・オブジェクトは別のRセッションでは正しく動作しません。

OML4Rプロキシ・オブジェクト、および任意のRオブジェクトは、ore.save関数を使用して保存できます。ore.save関数はOML4Rデータストアを指定します。データストアは、Rセッションの終了時にデータベースに保持されます。データストアは、自身が含まれているオブジェクトの参照整合性を保持します。ore.load関数を使用して、データストア内のオブジェクトを別のRセッションにリストアできます。

データストアを使用して、次のことを実行できます。

  • OML4Rおよび作成したその他のRオブジェクトを1つのRセッションに保存し、別のRセッションにリストアします。

  • Embedded R Executionで使用するためにR関数に引数を渡します。

  • Embedded R Executionで使用するためにオブジェクトを渡します。たとえば、OREdmパッケージ内の関数を使用してOracle Machine Learning for SQLモデルを構築し、それをデータストアに保存することもできます。その後、Embedded R Executionを介してそのモデルを使用してデータベースのデータをスコアリングできます。Embedded R Execution関数でのデータストアの使用例は、例10-6を参照してください。

次の表にデータストアを操作する関数をリストし、その簡単な説明を示します。

表3-1 データストアを操作する関数

関数 説明

ore.datastore

現行のOracle Databaseスキーマのデータストアに関する情報をリストします。

ore.datastoreSummary

現行のOracle Databaseスキーマの指定したデータストアに関する詳細な情報を提供します。

ore.delete

現行のOracle Databaseスキーマからデータストアを削除します。

ore.grant データストアへ読取りアクセス権を付与します。

ore.lazyLoad

データストアからオブジェクトをR環境に遅延リストアします。

ore.load

データストアからオブジェクトをR環境にリストアします。

ore.revoke データストアへの読取りアクセス権を取り消します。

ore.save

Rオブジェクトを新規または既存のデータストアに保存します。

関連項目:

Embedded R Executionに対するRインタフェースおよびSQLインタフェースの使用の詳細は、Oracle R EnterpriseのEmbedded R Executionの使用方法を参照してください。

3.2.3.5.2 OML4Rのデータストアについて

各データベース・スキーマには、指定したOML4Rのデータストアを格納する表があります。

データストアにはOML4Rオブジェクトおよび標準のRオブジェクトを含めることができます。

ore.save関数を使用してデータストアを作成できます。データストアの作成時にそのデータストアの名前を指定します。オブジェクトを1つ以上のデータストアに保存できます。

データストアにデータベース・オブジェクトのOML4Rプロキシ・オブジェクトが含まれているかぎり、データベース・オブジェクトはRセッション間で保持されます。たとえば、OREdmパッケージでore.odmNB関数を使用してOracle Machine Learning for SQLのNaive Bayesモデルを構築することもできます。構築されたore.odmNBオブジェクトをデータストアに保存してRセッションを終了した場合、Oracle DatabaseはそのOML4SQLモデルを削除しません。ore.odmNBオブジェクトが含まれいるデータストアがない場合は、Rセッションを終了すると、データベースは自動的にそのモデルを削除します。

3.2.3.5.3 データストアへのオブジェクトの保存

ore.save関数は、1つ以上のRオブジェクトを指定されたデータストアに保存します。

デフォルトでは、OML4Rは、現行のユーザー・スキーマにデータストアを作成します。ore.saveに対して引数を指定する場合、特定のオブジェクトの名前、またはオブジェクトのリストを指定できます。データストアへの読取りアクセス権を他のユーザーに付与できるかどうかを指定できます。特定のR環境を指定して保存するオブジェクトを検索できます。overwriteおよびappendの引数は相互に排他的です。overwrite引数をTRUEに設定した場合、既存のデータストアを同じ名前の別のデータストアで置換できます。append引数をTRUEに設定した場合、既存のデータストアにオブジェクトを追加できます。description引数を使用すると、データストアの情報取得時に表示される説明テキストを指定できます。description引数は、append引数とともに使用すると機能しません。

例3-18 オブジェクトの保存およびデータストアの作成

この例では、引数の様々な組合せを使用してデータストアを作成する方法を示します。

# Create some R objects.
df1 <- data.frame(x1 = 1:5, y1 = letters[1:5])
df2 <- data.frame(x2 = 5:1, y2 = letters[11:15])
iris_of <- ore.push(iris)

# Create a database table and an OML4R proxy object for the table.
ore.drop("AIRQUALITY")
ore.create(airquality, table = "AIRQUALITY")

# List the R objects.
ls()

# List the OML4R proxy objects.
ore.ls()

# Save the proxy object and all objects in the current workspace environment
# to the datastore named ds1 and supply a description.
ore.save(AIRQUALITY, list = ls(), name = "ds1", description = "My private datastore")

# Create some more objects.
x <- stats::runif(20)  # x is an object of type numeric.
y <- list(a = 1, b = TRUE, c = "hoopsa")
z <- ore.push(x)  # z is an object of type ore.numeric.

# Create another datastore.
ore.save(x, y, name = "ds2", description = "x and y")

# Overwrite the contents of datastore ds2.
ore.save(x, name = "ds2", overwrite = TRUE, description = "only x")

# Append object z to datastore ds2.
ore.save(z, name = "ds2", append = TRUE)

この例のリスト

R> # Create some R objects.
R> df1 <- data.frame(x1 = 1:5, y1 = letters[1:5])
R> df2 <- data.frame(x2 = 5:1, y2 = letters[11:15])
R> iris_of <- ore.push(iris)
R> 
R> # Create a database table and an OML4R proxy object for the table.
R> ore.drop("AIRQUALITY")
R> ore.create(airquality, table = "AIRQUALITY")
R> 
R> # List the R objects.
R> ls()
[1] "df1"     "df2"     "iris_of"
R> 
R> # List the OML4R proxy objects.
R> ore.ls()
[1] "AIRQUALITY"
R> 
R> # Save the proxy object and all objects in the current workspace environment
R> # to the datastore named ds1 and supply a description.
R> ore.save(AIRQUALITY, list = ls(), name = "ds1", description = "My datastore")
R> 
R> # Create some more objects.
R> x <- stats::runif(20)  # x is an object of type numeric.
R> y <- list(a = 1, b = TRUE, c = "hoopsa")
R> z <- ore.push(x)  # z is an object of type ore.numeric.
R> 
R> # Create another datastore.
R> ore.save(x, y, name = "ds2", description = "x and y")
R> 
R> # Overwrite the contents of datastore ds2.
R> ore.save(x, name = "ds2", overwrite = TRUE, description = "only x")
R> 
R> # Append object z to datastore ds2.
R> ore.save(z, name = "ds2", append = TRUE)
3.2.3.5.4 データストアへのアクセスの制御

ore.grant関数およびore.revoke関数を使用すると、OML4Rのデータストアへのアクセス権を付与したり、取り消すことができます。

ore.grantおよびore.revoke関数では、データストアへのアクセスを制御できます。自分が所有するデータストアへの読取りアクセス権を、指定したユーザーに付与したり、アクセス権限を取り消すことができます。関数ore.saveore.loadore.datastoreおよびore.datastoreSummaryには、データストアのアクセス権に関連する引数があります。

ノート:

ore.createを使用して永続データベース表およびそのプロキシore.frameオブジェクトを作成し、付与可能なデータストアにプロキシore.frameオブジェクトを保存した後、ore.grantを使用してデータストアへの読取りアクセス権を付与した場合、アクセス権はore.frameオブジェクトにのみ適用されます。読取りアクセス権は、永続データベース表には拡張されません。表自体への読取り権限を付与するには、適切なSQLコマンドを実行する必要があります。

例3-19 データストアへのアクセス権の付与および取消し

この例では、ローカルのRセッションからOracleデータベースにairqualityデータセットをプッシュしますが、これは、ore.frameオブジェクトAIRQUALITYとして、また、同じ名前の一時データベース表として存在します。この例では次に、AIRQUALITYオブジェクトをデータストアds3に保存し、そのデータストアへのアクセス権を他のユーザーに付与できるように指定します。type = grantableを指定して関数ore.datastoreをコールし、読取りアクセス権が付与されているすべてのデータストアを表示します。ds3データストアの読取り権限をSCOTTに付与します。その後、type = grantを指定してore.datastoreをコールし、読取りアクセス権が付与されているデータストアを表示します。SCOTTの読取り権限を取り消し、アクセス権が付与されているデータストアを再度表示します。

AIRQUALITY <- ore.push(airquality)
ore.save(AIRQUALITY, name = "ds3", 
         description = "My datastore 3", grantable  = TRUE)
ore.datastore(type = "grantable")
ore.datastore(type = "grant")
ore.grant("ds3", type = "datastore", user = "SCOTT")
ore.datastore(type = "grant")
ore.revoke("ds3", type = "datastore", user = "SCOTT")
ore.datastore(type = "grant")

この例のリスト

R> AIRQUALITY <- ore.push(airquality)
R> ore.save(AIRQUALITY, name = "ds3", 
+           description = "My datastore 3", grantable  = TRUE)
R> ore.datastore(type = "grantable")
  datastore.name object.count  size       creation.date    description
1            ds3            1  1451 2015-11-30 18:48:25 My datastore 3
R> ore.datastore(type = "grant")
[1] datastore.name grantee       
<0 rows> (or 0-length row.names)
R> ore.grant("ds3", type = "datastore", user = "SCOTT")
R> ore.datastore(type = "grant")
  datastore.name grantee
1            ds3   SCOTT
R> ore.revoke("ds3", type = "datastore", user = "SCOTT")
R> ore.datastore(type = "grant")
[1] datastore.name grantee       
<0 rows> (or 0-length row.names)
3.2.3.5.5 データストアのコンテンツに関する情報の取得

ore.datastore関数およびore.datastoreSummary関数を使用することで、現行のユーザー・スキーマのデータストアに関する情報を取得できます。

ore.datastore関数を使用して、データストアに関する基本的な情報をリストできます。特定のタイプのデータストアに関する情報を取得するには、オプションの文字列引数typeを使用できます。typeの有効な値は次のとおりです。

  • 現行のセッション・ユーザーが作成したデータストアをリストするuser。これはデフォルト値です。

  • 現行のセッション・ユーザーが他のユーザーに読取りアクセス権を付与できないデータストアをリストするprivate

  • 現行のセッション・ユーザーが読取りアクセス権を持っているすべてのデータストアをリストするall

  • 現行のセッション・ユーザーが他のユーザーに読取り権限を付与できるデータストアをリストするgrantable

  • 現行のセッション・ユーザーが他のユーザーに読取り権限を付与したデータストアをリストするgrant

  • 他のユーザーによって現行のセッション・ユーザーに読取り権限が付与されたデータストアをリストするgranted

タイプを指定しなかった場合、関数ore.datastoreは、データストア名、データストア内のオブジェクト数、データストアのサイズ、作成日および説明に対応する列を含むdata.frameオブジェクトを返します。行は、列datastore.nameによってアルファベット順にソートされます。タイプを指定した場合、この関数は、指定したタイプの列を含むdata.frameを返します。

名前または正規表現パターンを使用してデータストアを検索できます。

ore.datastoreSummary関数は、接続されているデータベースのユーザー・スキーマにあるデータストアに保存されたRオブジェクトに関する情報を返します。この関数は、data.frameを返します。オブジェクト名、オブジェクト・クラス、オブジェクトのサイズおよびオブジェクトの長さ(vectorの場合)または行および列の数(data.frameオブジェクトの場合)に対応する列を含みます。これは、1つの必須の引数としてデータストアの名前を取りますが、オプションの引数としてデータストアの所有者を取ることもできます。

例3-20 ore.datastore関数の使用方法

この例では、ore.datastore関数の使用方法を示します。

# Create some R objects.df1 <- data.frame(x1 = 1:5, y1 = letters[1:5])
df2 <- data.frame(x2 = 5:1, y2 = letters[11:15])
iris_of <- ore.push(iris)

# Create a database table and an OML4R proxy object for the table.
ore.drop("AIRQUALITY")
ore.create(airquality, table = "AIRQUALITY")
                                                                            
# Save the objects to a datastore named ds1 and supply a description.
ore.save(AIRQUALITY, list = ls(), name = "ds1", description = "My private datastore")

# Create some more objects.
x <- stats::runif(20) # x is an object of type numeric.
y <- list(a = 1, b = TRUE, c = "hoopsa")
z <- ore.push(x) # z is an object of type ore.numeric.

# Create other datastores.
ore.save(x, y, name = "ds2", description = "x and y")
ore.save(df1, df2, name = "dfobj", description = "df objects")
ore.save(x, y, z, name = "another_ds", description = "For pattern matching")

# List all of the datastore objects.
ore.datastore()

# List the specified datastore.
ore.datastore("ds1")

# List the datastore objects with names that include "ds".
ore.datastore(pattern = "ds")

この例のリスト

R> # Create some R objects.
R> df1 <- data.frame(x1 = 1:5, y1 = letters[1:5])
R> df2 <- data.frame(x2 = 5:1, y2 = letters[11:15])
R> iris_of <- ore.push(iris)
R> 
R> # Create a database table and an OML4R proxy object for the table.
R> ore.drop("AIRQUALITY")
R> ore.create(airquality, table = "AIRQUALITY")
R>                                                                             
R> # Save the objects to a datastore named ds1 and supply a description.
R> ore.save(AIRQUALITY, list = ls(), name = "ds1", description = "My private datastore")
R>
R> # Create some more objects.
R> x <- stats::runif(20) # x is an object of type numeric.
R> y <- list(a = 1, b = TRUE, c = "hoopsa")
R> z <- ore.push(x) # z is an object of type ore.numeric.
R>
R> # Create other datastores.
R> ore.save(x, y, name = "ds2", description = "x and y")
R> ore.save(df1, df2, name = "dfobj", description = "df objects")
R> ore.save(x, y, z, name = "another_ds", description = "For pattern matching")
R> 
R> # List all of the datastore objects.
R> ore.datastore()
  datastore.name object.count size       creation.date          description
1     another_ds            3 1284 2017-04-21 16:08:57 For pattern matching
2          dfobj            2  656 2017-04-21 16:08:38           df objects
3            ds1            4 3439 2017-04-21 16:03:55 My private datastore
4            ds2            2  314 2017-04-21 16:04:32              x and y

R> # List the specified datastore.
R> ore.datastore("ds1")
  datastore.name object.count size       creation.date          description
1            ds1            4 3439 2017-04-21 16:03:55 My private datastore

R> # List the datastore objects with names that include "ds".
R> ore.datastore(pattern = "ds")
  datastore.name object.count size       creation.date          description
1     another_ds            3 1284 2017-04-21 16:08:57 For pattern matching
2            ds1            4 3439 2017-04-21 16:03:55 My private datastore
3            ds2            2  314 2017-04-21 16:04:32              x and y

例3-21 ore.datastoreSummary関数の使用方法

この例では、ore.datastoreSummary関数の使用方法を示します。この例では、前の例で作成したデータストアを使用します。

ore.datastoreSummary("ds1")
ore.datastoreSummary("ds2")

この例のリスト

R> ore.datastoreSummary("ds1")
  object.name      class size length row.count col.count
1  AIRQUALITY  ore.frame 1213      6        NA         6
2         df1 data.frame  328      2         5         2
3         df2 data.frame  328      2         5         2
4     iris_of  ore.frame 1570      5        NA         5
R> ore.datastoreSummary("ds2")
  object.name   class size length row.count col.count
1           x numeric  182     20        NA        NA
2           y    list  132      3        NA        NA
3.2.3.5.6 データストアからのオブジェクトのリストア

ore.load関数は、データストアに保存したRオブジェクトをRグローバル環境(.GlobalEnv)にリストアします。

この関数は、リストアされるオブジェクトの名前を含む文字列ベクターを返します。

保存されたすべてのオブジェクトをロードするか、list引数を使用してロードするオブジェクトを指定できます。envir引数を使用すると、オブジェクトをロードする環境を指定できます。

例3-22 データストアからオブジェクトをリストアするためのore.load関数の使用方法

この例では、ore.load関数を使用して、例3-20で作成されたデータストアからオブジェクトをリストアする方法を示します。この例は、その例と同じRセッションで実行されます。

# List the R objects.
ls()

# List the datastores.
ore.datastore()

# Delete the x and z objects.
rm(x, z)
ls()

# Restore all of the objects in datastore ds2.
ore.load("ds2")

ls()

# After ending the R session and starting another session.
ls()
# The datastore objects persist between sessions.
ore.datastore()

# Restore some of the objects from datastore ds1.
ore.load("ds1", list = c("df1", "df2", "iris_of"))
ls()
例3-22のリスト
R> # List the R objects.
R> ls()
[1] "df1"     "df2"     "iris_of" "x"       "y"       "z"
R> 
R> # List the datastores.
R> ore.datastore()
  datastore.name object.count size       creation.date  description
1     another_ds            3 1243 2014-07-24 13:31:56 For pattern mattching
2          dfobj            2  656 2014-07-24 13:31:46            df objects
3            ds1            4 3162 2014-07-24 13:25:17          My datastore
4            ds2            2 1111 2014-07-24 13:27:26                only x
R> 
R> # Delete the x and z objects.
R> rm(x, z)
R> ls()
[1] "df1"     "df2"     "iris_of" "y"
R> 
R> # Restore all of the objects in datastore ds2.
R> ore.load("ds2")
[1] "x" "z"
R> 
R> ls()
[1] "df1"     "df2"     "iris_of" "x"       "y"       "z"
R> 
R> # After ending the R session and starting another session.
R> ls()
character(0)
R> # The datastore objects persist between sessions.
R> ore.datastore()
  datastore.name object.count size       creation.date           description
1     another_ds            3 1243 2014-07-24 13:31:56 For pattern mattching
2          dfobj            2  656 2014-07-24 13:31:46            df objects
3            ds1            4 3162 2014-07-24 13:25:17          My datastore
4            ds2            2 1111 2014-07-24 13:27:26                only x

R> # Restore some of the objects from datastore ds1.
R> ore.load("ds1", list = c("df1", "df2", "iris_of"))
[1] "df1"     "df2"     "iris_of"
R> ls()
[1] "df1"     "df2"     "iris_of"
3.2.3.5.7 データストアの削除

ore.delete関数を使用すると、OML4Rデータストアのオブジェクトを削除、またはデータストア自身を削除できます。

データストアを削除するには、名前を指定します。データストアから1つ以上のオブジェクトを削除するには、list引数を指定します。ore.delete関数は、削除したオブジェクトまたはデータストアの名前を返します。

データストアを削除すると、OML4Rは、削除したデータストアでRオブジェクトによって参照されていたすべての一時データベース・オブジェクトを破棄します。Rオブジェクトを複数のデータストアに保存していた場合、OML4Rは、データストア内のオブジェクトが一時データベース・オブジェクトを参照していない場合にのみ、一時データベース・オブジェクトを破棄します。

例3-23 ore.delete関数の使用方法

この例では、ore.deleteを使用して、データストアからオブジェクトを削除した後、データストア全体を削除する方法を示します。この例では、例3-18で作成したオブジェクトを使用します。

# Delete the df2 object from the ds1 datastore.
ore.delete("ds1", list = "df2")
# Delete the datastore named ds1.
ore.delete("ds1")
例3-23のリスト
R> # Delete the df2 object from the ds1 datastore.
R> ore.delete("ds1", list = "df2")[1] "df2"
R> # Delete the datastore named ds1.
R> ore.delete("ds1")
[1] "ds1"
3.2.3.5.8 埋込みRの実行でのデータストアの使用について

データストアにオブジェクトを保存することによって、Embedded R Execution関数への引数の引渡し、およびRオブジェクトの参照が非常に容易になります。

1つのRセッションで作成したオブジェクトをデータベース内の単一のデータストアに保存できます。このデータストアの名前を埋込みR関数内でロードする引数として渡すことができます。データストアを使用して、1つのオブジェクトまたは複数のオブジェクトを簡単に渡すことができます。