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,它运行良好。 奇数。如果data
是data.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.vector
对data.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 > 3
的条件返回NA
,这在if
条件下不起作用。 (仅供参考,if
条件必须始终为长度 1,并且必须明确“真实”,即 TRUE
或 FALSE
,或 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 <- 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不存在或访问被拒绝