Microsoft SQL Server Management Studio 中的 R 脚本

Posted

技术标签:

【中文标题】Microsoft SQL Server Management Studio 中的 R 脚本【英文标题】:R scripts in Microsoft SQL Server Management Studio 【发布时间】:2022-01-16 22:59:59 【问题描述】:

我的问题是我无法理解这个环境的错误信息。我认为这是非常模糊的。现在我不明白问题出在哪里。

EXEC sp_execute_external_script
  @language = N'R',
  @script = N'
    count = 0; x=1; y=2; m="that is good until here"
    data = as.vector(data);
    for(i in data)
        if(data[y]>data[x])count=count+1; x=x+1; y=y+1
        elsex=x+1; y=y+1;
    count <- data.frame(count)',
    @output_data_1_name = N'count',
    @input_data_1_name = N'data',
    @input_data_1 = N'SELECT alcohol FROM [wine].[dbo].[wineT]'

【问题讨论】:

你能让这个 R 代码在没有 sql-server 或 ssms 的情况下在 R 控制台上工作吗? 是的,但这不是主要工作。他们使用这种方式只是为了测试。我将这段代码运行到 Rstudio,它运行良好。 奇数。如果datadata.frame,那么as.vector(data) 也是一个框架,这意味着for(i in data) 将迭代每一列(即唯一的列)。这样,在for 循环的第一次也是唯一一次迭代中,i 是一个向量,表示alcohol 是什么,我们会说一个numeric 的向量,长度大于1。继续,data[y]data[2],它失败,因为y 是2 而data 是单列框架。请原谅我持怀疑态度,但您的问题不可重复,而且您断言它有效的说法似乎值得怀疑。 我建议您通过提供示例数据使该脚本的 R 部分可重现。请参阅***.com/q/5963269、minimal reproducible example 和 ***.com/tags/r/info。然后edit 你的问题并添加来自dput(x) 的输出,其中x 是一个小的代表性样本。请在没有 sql 的情况下在控制台上显示实际(预期)输出。 是的,你真的是对的......我将“as.vector”更改为“unlist”,然后我收到“需要真/假的缺失值”的错误,然后我修复了这个错误,你猜怎么着?答对了。它解决了。顺便说一句,我没有很好的编程知识。并感谢您指导我。 【参考方案1】:

未经测试,试试这个:

EXEC sp_execute_external_script
  @language = N'R',
  @script = N'
    data = unlist(data);
    count = data.frame(count = sum(data[-length(data)] > data[-1]);',
  @output_data_1_name = N'count',
  @input_data_1_name = N'data',
  @input_data_1 = N'SELECT alcohol FROM [wine].[dbo].[wineT]'

问题:

    as.vectordata.frame 的作用不大,因此转移到unlist(data)

    您的missing value 错误是因为您将y 扩展到超出data 的长度。例如,在 R 控制台上,我可以使用以下命令重现错误:

    for (i in data)  if (data[y] > data[x])  count=count+1; x=x+1; y=y+1 else x=x+1; y=y+1 
    # Error in if (data[y] > data[x])  (from #1) : missing value where TRUE/FALSE needed
    count
    # [1] 4
    x
    # [1] 10
    y
    # [1] 11
    

    由于length(data) 是10,那么data[y]data[11]NA。这导致NA &gt; 3 的条件返回NA,这在if 条件下不起作用。 (仅供参考,if 条件必须始终为长度 1,并且必须明确“真实”,即 TRUEFALSE,或 0 为假而其他任何内容为真的数字。)

    另一种方法是创建 i 作为 data 上的索引从 2 开始

    count <- 0
    for(i in seq_along(data)[-1])  if (data[i-1] > data[i])  count=count+1 ; x=x+1; y=y+1; 
    count
    # [1] 4
    

    其中seq_along(data) 产生(在此示例中)1:10,但[-1] 删除了第一个1,因此我们可以安全地 索引从2 到data 的长度。

    不过,更好的是,我们根本不需要循环:您要做的就是将每个值(第一个值除外)与前一个值进行比较,然后计算前一个数字大多少倍。 R 向量化得非常好,因此我们可以在一个表达式中确定满足该条件的表达式,然后sum 以同样快的速度提升它们。

    data
    #  a1  a2  a3  a4  a5  a6  a7  a8  a9 a10 
    #   1   5  10   8   2   4   6   9   7   3 
    data[-length(data)] > data[-1]
    #    a1    a2    a3    a4    a5    a6    a7    a8    a9 
    # FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE 
    

    sum(..) 得到我们需要的结果。

【讨论】:

我运行你的答案,我得到一个错误,所以我稍微改变你的代码。我从 data.frame 函数中得到“count”计算,然后计算“count”的 data.frame。这次我得到了没有错误的结果。但我认为结果不正确。 我回答了 Advent of Code 2021 的第一个问题......所以我知道答案是 1451,但你的代码给了我 548。我知道我只能使用 R,而不是 R 脚本在 SQL 中......但它是用于培训的。顺便说一句,我非常感谢您的帮助 如果您的问题包括已知样本数据和预期结果,我将能够提供更多帮助。我用相当简单的数据 (data &lt;- data.frame(a=sample(10))) 进行了测试,它似乎有效。除非您分享,否则我无法测试您的数据。请参阅 ***.com/q/5963269、minimal reproducible example 和 ***.com/tags/r/info,了解有关可重现问题的说明。【参考方案2】:

我知道这不是一个整洁有效的答案,但我用这段代码得到了正确的答案。

  EXEC sp_execute_external_script
      @language = N"R",
      @script = N"
        count=0; x=1; y=2; z=NA;
        data = unlist(data);
        for(i in data)
            if(is.na(z))z=FALSEelse
            if(data[y]>data[x])count=count+1; x=x+1; y=y+1
            elsex=x+1; y=y+1;
        count <- data.frame(count)",
        @output_data_1_name = N"count",
        @input_data_1_name = N"data",
        @input_data_1 = N"SELECT column1 FROM [wine].[dbo].[data]"

【讨论】:

以上是关于Microsoft SQL Server Management Studio 中的 R 脚本的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft SQL Server Management Studio 已超过了锁请求超时时段。 (Microsoft SQL Server,错误: 1222)

java.sql.SQLException [Microsoft] [ODBC SQL Server Driver] [SQL Server] 对象名“表名”无效

Microsoft SQL Server Version List(SQL Server 版本)

Microsoft SQL Server 2017 Express and Management Studio Express

Microsoft][ODBC SQL Server Driver][DBNETLIB]SQL Server不存在或访问被拒绝

Microsoft SQL Server,错误: 3702