Microsoft SQL Server Management Studio 中的 R 脚本

R scripts in Microsoft SQL Server Management Studio

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

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}
        else{x=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]'

未经测试,试试这个:

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]'

问题:

  1. as.vectordata.frame 影响不大,因此转移到 unlist(data);

  2. 您的 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 > 3 which returns NAif 条件中不起作用。 (仅供参考,if 条件必须始终为 length-1,并且必须明确“真实”,意思是 TRUEFALSE,或者 0 为假的数字其他都是真的。)

  3. 另一种方法是创建 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.

    的长度
  4. 不过,更好的是我们根本不需要循环:您要做的就是将每个值(第一个除外)与前面的值进行比较并计算循环次数以前的数字更大。 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(..) 达到我们需要的结果。

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

  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=FALSE}else{
            if(data[y]>data[x]){count=count+1; x=x+1; y=y+1}
            else{x=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]"