Schnellstart: Datenstrukturen, Datentypen und Objekte bei Verwendung von R mit SQL Machine LearningQuickstart: Data structures, data types, and objects using R with SQL machine learning

Anwendungsbereich:Applies to: JaSQL Server 2016 (13.x)SQL Server 2016 (13.x)yesSQL Server 2016 (13.x)SQL Server 2016 (13.x) und höher JaVerwaltete Azure SQL-InstanzAzure SQL Managed InstanceYesVerwaltete Azure SQL-InstanzAzure SQL Managed InstanceAnwendungsbereich:Applies to: JaSQL Server 2016 (13.x)SQL Server 2016 (13.x)yesSQL Server 2016 (13.x)SQL Server 2016 (13.x) and later JaVerwaltete Azure SQL-InstanzAzure SQL Managed InstanceYesVerwaltete Azure SQL-InstanzAzure SQL Managed Instance

In dieser Schnellstartanleitung erfahren Sie, wie Sie Datenstrukturen und Datentypen bei Verwendung von R in SQL Server Machine Learning Services oder in Big Data-Clustern verwenden können.In this quickstart, you'll learn how to use data structures and data types when using R in SQL Server Machine Learning Services or on Big Data Clusters. Sie erhalten Informationen zum Verschieben von Daten zwischen R und SQL Server und zu Fehlern, die in diesem Zusammenhang häufig auftreten.You'll learn about moving data between R and SQL Server, and the common issues that might occur.

In dieser Schnellstartanleitung erfahren Sie, wie Sie Datenstrukturen und Datentypen bei Verwendung von R in SQL Server Machine Learning Services verwenden können.In this quickstart, you'll learn how to use data structures and data types when using R in SQL Server Machine Learning Services. Sie erhalten Informationen zum Verschieben von Daten zwischen R und SQL Server und zu Fehlern, die in diesem Zusammenhang häufig auftreten.You'll learn about moving data between R and SQL Server, and the common issues that might occur.

In dieser Schnellstartanleitung erfahren Sie, wie Sie Datenstrukturen und Datentypen bei Verwendung von R in SQL Server R Services verwenden können.In this quickstart, you'll learn how to use data structures and data types when using R in SQL Server R Services. Sie erhalten Informationen zum Verschieben von Daten zwischen R und SQL Server und zu Fehlern, die in diesem Zusammenhang häufig auftreten.You'll learn about moving data between R and SQL Server, and the common issues that might occur.

In dieser Schnellstartanleitung erfahren Sie, wie Sie Datenstrukturen und -typen mit R in Machine Learning Services in Azure SQL Managed Instance verwenden können.In this quickstart, you'll learn how to use data structures and data types when using R in Azure SQL Managed Instance Machine Learning Services. Außerdem erhalten Sie Informationen zum Verschieben von Daten zwischen R und SQL Managed Instance und zu Fehlern, die in diesem Zusammenhang häufig auftreten.You'll learn about moving data between R and SQL Managed Instance, and the common issues that might occur.

Diese häufig auftretenden Probleme sollten Sie im Vorfeld kennen:Common issues to know up front include:

  • Datentypen stimmen manchmal nicht übereinData types sometimes don't match
  • Es können implizite Konvertierungen auftretenImplicit conversions might take place
  • Umwandlungs- und Konvertierungsvorgänge sind ggf. erforderlichCast and convert operations are sometimes required
  • Für R und SQL werden unterschiedliche Datenobjekte genutztR and SQL use different data objects

VoraussetzungenPrerequisites

Zum Durchführen dieser Schnellstartanleitung benötigen Sie folgende Voraussetzungen.You need the following prerequisites to run this quickstart.

  • Ein Tool zum Ausführen von SQL-Abfragen, die R-Skripts enthalten.A tool for running SQL queries that contain R scripts. In dieser Schnellstartanleitung wird Azure Data Studio verwendet.This quickstart uses Azure Data Studio.

Geben Sie immer einen Datenrahmen zurückAlways return a data frame

Wenn Ihr Skript Ergebnisse von R zum SQL Server zurückgibt, muss es die Daten als data.frame zurückgeben.When your script returns results from R to SQL Server, it must return the data as a data.frame. Jede andere Objektart, die Sie in Ihrem Skript generieren –, d.h. eine Liste, ein Faktor, ein Vektor oder binäre Daten – müssen zu einem Datenrahmen konvertiert werden, wenn sie als Teil der gespeicherten Prozedurergebnisse ausgegeben werden sollen.Any other type of object that you generate in your script - whether that be a list, factor, vector, or binary data - must be converted to a data frame if you want to output it as part of the stored procedure results. Glücklicherweise gibt es mehrere R-Funktionen zur Unterstützung von sich ändernden Objekten in einem Datenrahmen.Fortunately, there are multiple R functions to support changing other objects to a data frame. Sie können auch ein binäres Modell serialisieren und es in einen Datenrahmen zurückgeben. Mehr dazu erfahren Sie später in diesem Schnellstart.You can even serialize a binary model and return it in a data frame, which you'll do later in this quickstart.

Zunächst experimentieren wir mit einigen R-basierten R-Objekten, Vektoren, Matrizen und Listen – und sehen, wie die Konvertierung in einen Datenrahmen die Ausgabe an die SQL Server-Instanz ändert.First, let's experiment with some R basic R objects - vectors, matrices, and lists - and see how conversion to a data frame changes the output passed to SQL Server.

Vergleichen Sie diese beiden „Hallo Welt“-Skripts in R. Die Skripts sehen fast identisch aus, aber das erste gibt eine einzelne Spalte mit drei Werten zurück, während das zweite drei Spalten mit jeweils einem einzigen Wert zurückgibt.Compare these two "Hello World" scripts in R. The scripts look almost identical, but the first returns a single column of three values, whereas the second returns three columns with a single value each.

Beispiel 1Example 1

EXECUTE sp_execute_external_script
       @language = N'R'
     , @script = N' mytextvariable <- c("hello", " ", "world");
       OutputDataSet <- as.data.frame(mytextvariable);'
     , @input_data_1 = N' ';

Beispiel 2Example 2

EXECUTE sp_execute_external_script
        @language = N'R'
      , @script = N' OutputDataSet<- data.frame(c("hello"), " ", c("world"));'
      , @input_data_1 = N'  ';

Identifizieren von Schema- und DatentypenIdentify schema and data types

Warum sind die Ergebnisse so unterschiedlich?Why are the results so different?

Die Antwort kann normalerweise mit dem R-Befehl str() ermittelt werden.The answer can usually be found by using the R str() command. Fügen Sie die Funktion str(object_name) an einer beliebigen Stelle in Ihrem R-Skript hinzu, damit das Datenschema des angegebenen R-Objekts als Informationsnachricht zurückgegeben wird.Add the function str(object_name) anywhere in your R script to have the data schema of the specified R object returned as an informational message.

Fügen Sie die Zeile str(OutputDataSet) wie folgt am Ende der Variablen @script in jeder Anweisung ein, um zu ermitteln, warum Beispiel 1 und 2 so unterschiedliche Ergebnisse aufweisen:To figure out why Example 1 and Example 2 have such different results, insert the line str(OutputDataSet) at the end of the @script variable definition in each statement, like this:

Beispiel 1 mit hinzugefügter str-FunktionExample 1 with str function added

EXECUTE sp_execute_external_script
        @language = N'R'
      , @script = N' mytextvariable <- c("hello", " ", "world");
      OutputDataSet <- as.data.frame(mytextvariable);
      str(OutputDataSet);'
      , @input_data_1 = N'  '
;

Beispiel 2 mit hinzugefügter str-FunktionExample 2 with str function added

EXECUTE sp_execute_external_script
  @language = N'R', 
  @script = N' OutputDataSet <- data.frame(c("hello"), " ", c("world"));
    str(OutputDataSet);' , 
  @input_data_1 = N'  ';

Überprüfen Sie nun den Text unter Nachrichten, um zu ermitteln, warum sich die Ausgabe unterscheidet.Now, review the text in Messages to see why the output is different.

Ergebnisse: Beispiel 1Results - Example 1

STDOUT message(s) from external script:
'data.frame':   3 obs. of  1 variable:
$ mytextvariable: Factor w/ 3 levels " ","hello","world": 2 1 3

Ergebnisse: Beispiel 2Results - Example 2

STDOUT message(s) from external script:
'data.frame':   1 obs. of  3 variables:
$ c..hello..: Factor w/ 1 level "hello": 1
$ X...      : Factor w/ 1 level " ": 1
$ c..world..: Factor w/ 1 level "world": 1

Sie sehen, dass eine geringfügige Änderung der R-Syntax eine große Auswirkung auf das Schema mit den Ergebnissen hat.As you can see, a slight change in R syntax had a big effect on the schema of the results. Wir gehen nicht näher auf den Grund dafür ein, da die Unterschiede der R-Datentypen detaillierter im Abschnitt Data Structures (Datenstrukturen) des Artikels „Advanced R“ von Hadley Wickham erläutert werden.We won't go into why, but the differences in R data types are explained in details in the Data Structures section in "Advanced R" by Hadley Wickham.

Vorerst sollten Sie nur bedenken, dass Sie die erwarteten Ergebnisse überprüfen sollten, wenn Sie für R-Objekte Datenrahmen verwenden.For now, just be aware that you need to check the expected results when coercing R objects into data frames.

Tipp

Sie können auch R-Identitätsfunktionen wie is.matrix, is.vector, verwenden, um Informationen über die interne Datenstruktur zurückzugeben.You can also use R identity functions, such as is.matrix, is.vector, to return information about the internal data structure.

Implizite Konvertierung von DatenobjektenImplicit conversion of data objects

Jedes R-Datenobjekt verfügt über eigene Regeln zur Verarbeitung von Werten, wenn diese mit anderen Datenobjekten kombiniert werden. Es wird auch überprüft, ob die beiden Datenobjekte die gleiche Anzahl von Dimensionen aufweisen oder ob ein Datenobjekt heterogene Datentypen enthält.Each R data object has its own rules for how values are handled when combined with other data objects if the two data objects have the same number of dimensions, or if any data object contains heterogeneous data types.

Erstellen Sie zunächst eine kleine Tabelle mit Testdaten.First, create a small table of test data.

CREATE TABLE RTestData (col1 INT NOT NULL)

INSERT INTO RTestData
VALUES (1);

INSERT INTO RTestData
VALUES (10);

INSERT INTO RTestData
VALUES (100);
GO

Nehmen wir beispielsweise an, dass Sie die folgende Anweisung zur Matrixmultiplikation mit R ausführen. Sie vervielfältigen eine einspaltige Matrix mit den drei Werten durch ein Array mit vier Werten und erwarten daher, dass eine 4 x 3-Matrix entsteht.For example, assume you run the following statement to perform matrix multiplication using R. You multiply a single-column matrix with the three values by an array with four values, and expect a 4x3 matrix as a result.

EXECUTE sp_execute_external_script
    @language = N'R'
    , @script = N'
        x <- as.matrix(InputDataSet);
        y <- array(12:15);
    OutputDataSet <- as.data.frame(x %*% y);'
    , @input_data_1 = N' SELECT [Col1]  from RTestData;'
    WITH RESULT SETS (([Col1] int, [Col2] int, [Col3] int, Col4 int));

Im Hintergrund wird die Spalte mit drei Werten in eine Matrix mit einer Spalte konvertiert.Under the covers, the column of three values is converted to a single-column matrix. Da eine Matrix lediglich einen Sonderfall eines Arrays in R darstellt, wird das Array y implizit in eine Matrix mit nur einer Spalte umgewandelt, damit die beiden Argumente konform sind.Because a matrix is just a special case of an array in R, the array y is implicitly coerced to a single-column matrix to make the two arguments conform.

ErgebnisseResults

Col1Col1 Col2Col2 Col3Col3 Col4Col4
1212 1313 1414 1515
120120 130130 140140 150150
12001200 13001300 14001400 15001500

Beachten Sie jedoch, was geschieht, wenn Sie die Größe des Arrays y ändern.However, note what happens when you change the size of the array y.

execute sp_execute_external_script
   @language = N'R'
   , @script = N'
        x <- as.matrix(InputDataSet);
        y <- array(12:14);
   OutputDataSet <- as.data.frame(y %*% x);'
   , @input_data_1 = N' SELECT [Col1]  from RTestData;'
   WITH RESULT SETS (([Col1] int ));

R gibt jetzt einen einzelnen Wert als Ergebnis zurück.Now R returns a single value as the result.

ErgebnisseResults

Col1Col1
15421542

Warum?Why? In diesem Fall, gibt R das innere Produkt als Matrix zurück, da die beiden Argumente als Vektoren derselben Länge verarbeitet werden können.In this case, because the two arguments can be handled as vectors of the same length, R returns the inner product as a matrix. Dies ist das erwartete Verhalten gemäß der Regeln der linearen Algebra. Es kann jedoch Probleme verursachen, wenn die Downstream-Anwendung erwartet, dass das Ausgabeschema sich nie ändert!This is the expected behavior according to the rules of linear algebra; however, it could cause problems if your downstream application expects the output schema to never change!

Tipp

Erhalten Sie Fehler?Getting errors? Stellen Sie sicher, dass Sie die gespeicherte Prozedur im Kontext der Datenbank ausführen, die die Tabelle enthält, und nicht in Master oder einer anderen Datenbank.Make sure that you're running the stored procedure in the context of the database that contains the table, and not in master or another database.

Außerdem wird empfohlen, für diese Beispiele keine temporären Tabellen zu verwenden.Also, we suggest that you avoid using temporary tables for these examples. Einige R-Clients beenden eine Verbindung zwischen Batches und löschen temporäre Tabellen.Some R clients will terminate a connection between batches, deleting temporary tables.

Zusammenführen oder Multiplizieren von Spalten unterschiedlicher LängeMerge or multiply columns of different length

R bietet ein hohes Maß an Flexibilität für die Arbeit mit Vektoren verschiedener Größen und für die Kombination dieser spaltenähnlichen Strukturen in Datenrahmen.R provides great flexibility for working with vectors of different sizes, and for combining these column-like structures into data frames. Die Liste mit den Vektoren kann wie eine Tabelle aussehen, aber es werden nicht alle Regeln eingehalten, die für Datenbanktabellen gelten.Lists of vectors can look like a table, but they don't follow all the rules that govern database tables.

Mit dem folgenden Skript wird beispielsweise ein numerisches Array der Länge 6 definiert und unter der R-Variablen df1 gespeichert.For example, the following script defines a numeric array of length 6 and stores it in the R variable df1. Das numerische Array wird anschließend mit den ganzen Zahlen der RTestData-Tabelle kombiniert, die drei Werte enthält, um einen neuen Datenrahmen, df2, zu erstellen.The numeric array is then combined with the integers of the RTestData table, which contains three (3) values, to make a new data frame, df2.

EXECUTE sp_execute_external_script
    @language = N'R'
    , @script = N'
               df1 <- as.data.frame( array(1:6) );
               df2 <- as.data.frame( c( InputDataSet , df1 ));
               OutputDataSet <- df2'
    , @input_data_1 = N' SELECT [Col1]  from RTestData;'
    WITH RESULT SETS (( [Col2] int not null, [Col3] int not null ));

Zum Ausfüllen des Datenrahmens wiederholt R die aus „RTestData“ abgerufenen Elemente so oft wie nötig, um die gleiche Anzahl von Elementen wie im Array df1 zu erzielen.To fill out the data frame, R repeats the elements retrieved from RTestData as many times as needed to match the number of elements in the array df1.

ErgebnisseResults

Col2Col2 Col3Col3
11 11
1010 22
100100 33
11 44
1010 55
100100 66

Beachten Sie, dass der Datenrahmen nur wie eine Tabelle aussieht, aber eigentlich eine Vektorenliste ist.Remember that a data frame only looks like a table, and is actually a list of vectors.

Umwandeln oder Konvertieren von DatenCast or convert data

R und SQL Server verwenden nicht die gleichen Datentypen, sodass Sie eine Abfrage im SQL Server durchführen können, um Daten abzurufen und diese an die R-Laufzeit zu übergeben, erfolgt in der Regel eine Art implizite Konvertierung.R and SQL Server don't use the same data types, so when you run a query in SQL Server to get data and then pass that to the R runtime, some type of implicit conversion usually takes place. Eine weitere Reihe von Konvertierungen findet statt, wenn Sie Daten von R an SQL Server zurückgeben.Another set of conversions takes place when you return data from R to SQL Server.

  • SQL Server überträgt die Daten aus der Abfrage an den vom Launchpad-Dienst verwalteten R-Prozess und konvertiert sie in eine interne Darstellung zur Effizienzsteigerung.SQL Server pushes the data from the query to the R process managed by the Launchpad service and converts it to an internal representation for greater efficiency.
  • Die R-Runtime lädt die Daten in eine data.frame-Variable und führt eigene Vorgänge für die Daten durch.The R runtime loads the data into a data.frame variable and performs its own operations on the data.
  • Die Datenbank-Engine gibt die Daten über eine sichere interne Verbindung an den SQL Server zurück und zeigt die Daten in Form von SQL Server-Datentypen.The database engine returns the data to SQL Server using a secured internal connection and presents the data in terms of SQL Server data types.
  • Sie rufen Sie Daten über eine Verbindung mit dem SQL Server mithilfe einer Client- oder Netzwerk-Bibliothek auf, die SQL-Abfragen und tabellarische Datensätze verarbeiten kann.You get the data by connecting to SQL Server using a client or network library that can issue SQL queries and handle tabular data sets. Diese Clientanwendung kann sich unter Umständen auch auf andere Art und Weise auf die Daten auswirken.This client application can potentially affect the data in other ways.

Um zu sehen, wie dies funktioniert, führen Sie eine Abfrage, wie diese im Datawarehouse AdventureWorksDW durch.To see how this works, run a query such as this one on the AdventureWorksDW data warehouse. In dieser Ansicht werden Verkaufsdaten zurückgegeben, die zum Erstellen von Vorhersagen verwendet werden.This view returns sales data used in creating forecasts.

USE AdventureWorksDW
GO

SELECT ReportingDate
         , CAST(ModelRegion as varchar(50)) as ProductSeries
         , Amount
           FROM [AdventureWorksDW].[dbo].[vTimeSeries]
           WHERE [ModelRegion] = 'M200 Europe'
           ORDER BY ReportingDate ASC

Hinweis

Sie können eine beliebige Version von AdventureWorks verwenden oder eine andere Abfrage mit einer eigenen Datenbank erstellen.You can use any version of AdventureWorks, or create a different query using a database of your own. Es geht darum zu versuchen, einige Daten mit Text, Datum/Uhrzeit und numerischen Werten zu verarbeiten.The point is to try to handle some data that contains text, datetime and numeric values.

Versuchen Sie jetzt, diese Abfrage als Eingabe für die gespeicherte Prozedur einzufügen.Now, try pasting this query as the input to the stored procedure.

EXECUTE sp_execute_external_script
       @language = N'R'
      , @script = N' str(InputDataSet);
      OutputDataSet <- InputDataSet;'
      , @input_data_1 = N'
           SELECT ReportingDate
         , CAST(ModelRegion as varchar(50)) as ProductSeries
         , Amount
           FROM [AdventureWorksDW].[dbo].[vTimeSeries]
           WHERE [ModelRegion] = ''M200 Europe''
           ORDER BY ReportingDate ASC ;'
WITH RESULT SETS undefined;

Wenn Sie einen Fehler erhalten, müssen Sie unter Umständen einige Änderungen am Abfragetext vornehmen.If you get an error, you'll probably need to make some edits to the query text. Beispielsweise muss das Zeichenfolgenprädikat in der WHERE-Klausel doppelt in einfache Anführungszeichen gesetzt werden.For example, the string predicate in the WHERE clause must be enclosed by two sets of single quotation marks.

Wenn die Abfrage funktioniert, sollten Sie sich die Ergebnisse der str-Funktion ansehen, um zu ermitteln, wie die Eingabedaten von R verarbeitet werden.After you get the query working, review the results of the str function to see how R treats the input data.

ErgebnisseResults

STDOUT message(s) from external script: 'data.frame':    37 obs. of  3 variables:
STDOUT message(s) from external script: $ ReportingDate: POSIXct, format: "2010-12-24 23:00:00" "2010-12-24 23:00:00"
STDOUT message(s) from external script: $ ProductSeries: Factor w/ 1 levels "M200 Europe",..: 1 1 1 1 1 1 1 1 1 1
STDOUT message(s) from external script: $ Amount       : num  3400 16925 20350 16950 16950
  • Die Spalte für Datums-/Uhrzeitangaben wurde mit dem R-Datentyp POSIXct verarbeitet.The datetime column has been processed using the R data type, POSIXct.
  • Die Text-Spalte „ProductSeries“ wurde als ein Faktor erkannt, d.h. eine kategorische Variable.The text column "ProductSeries" has been identified as a factor, meaning a categorical variable. Zeichenfolgenwerte werden standardmäßig als Faktoren verarbeitet.String values are handled as factors by default. Wenn Sie eine Zeichenfolge an R übergeben, wird sie in eine ganze Zahl für die interne Verwendung konvertiert und in der Ausgabe dann wieder der Zeichenfolge zugeordnet.If you pass a string to R, it is converted to an integer for internal use, and then mapped back to the string on output.

ZusammenfassungSummary

Aus diesen kurzen Beispielen können Sie ersehen, dass die Auswirkungen der Datenkonvertierung überprüft werden müssen, wenn SQL-Abfragen als Eingabe übergeben werden.From even these short examples, you can see the need to check the effects of data conversion when passing SQL queries as input. Da einige SQL Server-Datentypen von R nicht unterstützt werden, ziehen Sie die folgenden Methoden in Betracht, um Fehler zu vermeiden:Because some SQL Server data types are not supported by R, consider these ways to avoid errors:

  • Testen Sie die Daten im Voraus, und überprüfen Sie Spalten oder Werte in Ihrem Schema, die ein Problem darstellen können, wenn sie dem R-Code übergeben werden.Test your data in advance and verify columns or values in your schema that could be a problem when passed to R code.
  • Geben Sie Spalten in Ihrer Eingabedatenquelle einzeln an, anstatt SELECT * zu verwenden, und machen Sie sich damit vertraut, wie die einzelnen Spalten verarbeitet werden.Specify columns in your input data source individually, rather than using SELECT *, and know how each column will be handled.
  • Führen Sie nach Bedarf explizite Umwandlungen durch, wenn Sie Ihre Eingabedaten vorbereiten, um Überraschungen zu vermeiden.Perform explicit casts as necessary when preparing your input data, to avoid surprises.
  • Vermeiden Sie das Übergeben von Datenspalten (z. B. GUIDs oder RowGUIDS), die Fehler verursachen und nicht für die Modellierung nützlich sind.Avoid passing columns of data (such as GUIDs or rowguids) that cause errors and aren't useful for modeling.

Weitere Informationen zu unterstützten und nicht unterstützten Datentypen finden Sie unter R-Bibliotheken und -Datentypen.For more information on supported and unsupported data types, see R libraries and data types.

Nächste SchritteNext steps

Weitere Informationen zum Schreiben von erweiterten R-Funktionen mit SQL Machine Learning finden Sie in diesem Schnellstart:To learn about writing advanced R functions with SQL machine learning, follow this quickstart: