FAQ > 金融建模 > 第三方交互 > R

Q:如何解决R语言4.2.0及以上版本原生支持UTF-8导致交互转码引起的异常    

  • A:R语言在4.2.0+版本上实现了对UTF-8的原生支持,但天软默认的是gbk格式,在交互时可能会出现以下异常:
    1.通过代码串交互式会将代码串转为UTF-8格式,天软无法识别,导致执行异常
    2.交互获取的结果集返回到R时会自动转化为UTF-8的格式,部分字符无法直接转化导致转码异常
    对于异常1:
      方法一.可通过天软函数Utf8toansi将交互代码串由UTF8串转为Ansi串提交给天软正常执行
      方法二.可通过R语言中的模型iconv将字符串UTF8串转为Ansi串提交给天软正常执行

    对于异常2:可通过模型AnsiToUtf8先将结果集中的字符串转为UTF8格式,返回到R中可以正常识别
    别说明特:对于字符进行转码是只对中文格式输入的字符产生影响,在使用过程中可以只转换中文格式字符串
    函数说明
    FAQ:UTF8ToAnsi
    FAQ:AnsiToUTF8
    交互范例:
    环境说明:使用64位4.2.1版的R语言与天软进行交互,默认编码环境Chinese (Simplified)_China.utf8
    可以通过代码:Sys.setlocale(category="LC_ALL",local="")设置R的默认编码环境

    ODBC交互
    FAQ:2014-09-26-应用专题-第三方交互05:天软平台与 R 的交互
    范例一:调用天软函数的方式
    在天软中新建函数:R_test

    Function R_test();
    Begin
      t:= Query("科创板","",True,"",
           AnsiToUtf8("代码"),DefaultStockID(),
           "name",CurrentStockName(),
           "firstday",StockGoMarketDate());
      t[:,"name"]:= AnsiToUtf8(t[:,"name"]);
      return t;
    End;

    R交互代码:

    library(RODBC)
    channel=odbcConnect("jh_test")
    sqlstr="return R_test();"
    t=sqlQuery(channel,sqlstr)
    t
    执行结果:


    范例二:执行天软代码的方式
    R代码:

    library(RODBC)
    channel=odbcConnect("jh_test")
    sqlstr='t:= Query(utf8toansi("深证A股;上证A股;中小企业板;创业板;科创板"),"",True,"","代码",DefaultStockID(),"名称",CurrentStockName(),"上市日",StockGoMarketDate());t[:,"名称"]:= AnsiToUtf8(t[:,"名称"]);return t;'
    t=sqlQuery(channel,sqlstr)
    t
    执行结果:


    基于tslr.dll交互
    FAQ:2014-11-17-应用专题-第三方交互06:天软平台与R交互(基于TSLR.DLL和ODBC两种方式)
    范例三:调用天软函数的方式
    R代码:

    dyn.load("C:/program files/Tinysoft/Analyse.NET/tslr.dll")
    server=.External("tslConnectServer","tsl.tinysoft.com.cn",443,NULL)
    dl=.External("tslLoginServer","user","password")
    t=.External("tslRemoteCallFunc","R_test",NULL,NULL)
    t
    执行结果:


    范例四:执行天软代码的方式
    R代码:

    dyn.load("C:/program files/Tinysoft/Analyse.NET/tslr.dll")
    server=.External("tslConnectServer","tsl.tinysoft.com.cn",443,NULL)
    dl=.External("tslLoginServer","user","password")
    sqlstr='t:=Query(utf8toansi("深证A股;上证A股;创业板;科创板"),"",True,"","代码",DefaultStockID(),"名称",CurrentStockName(),"上市日",StockGoMarketDate());t[:,"名称"]:= AnsiToUtf8(t[:,"名称"]);return t;'
    t=.External("tslRemoteExecute",sqlstr,list())
    t[[2]][[10]]
    执行结果:


    对返回结果批量转换
    在实际交互取数中往会存在多列数据需要转换的情况,可以使用矩阵遍历模型做全量转换
    注意:转码是针对字符串格式数据做转化,转换模型只支持字符串格式数据
    参考
    FAQ:::与::=的应用举例
    FAQ:?:判断求值三元运算符
    范例五:对返回结果做全量转换
    R代码:

    library(RODBC)
    channel <- odbcConnect("tsodbc")
    sqlstr <- paste0('
    t := Query(utf8toansi("深证A股;上证A股;创业板;科创板;北证A股"),"",True,"",
    "代码",DefaultStockID(),
    "名称",CurrentStockName(),
    "截止日",report(40000,20231231),
    "公布日",report(40001,20231231),
    "预警内容",report(40003,20231231),
    "预警类型",report(40002,20231231));
    t ::= ifstring(mcell) ? ansitoutf8(mcell) : mcell;
    return t;
    ')
    t <- sqlQuery(channel,sqlstr)
    print(tail(t,5))
    执行结果:


    转换列名
    部分天软模型返回的列名带有中文格式的需要进行转换
    参考:FAQ:Q:如何修改数组的列名(列下标)
    范例六:所有列名全量转换
    R代码

    library(RODBC)
    channel <- odbcConnect("tsodbc")
    sqlstr <- '
    GetBkWeightByDate("SH000300",20230116T,t);
    t ::= ifstring(mcell) ? ansitoutf8(mcell) : mcell;
    //批量替换列名
    names:=ansitoutf8(mcols(t,1));
    t1:=Zeros(mrows(t),names);
    t1[:,:]:=t;

    return t1;'
    xxx <- sqlQuery(channel,sqlstr)
    print(xxx)
    执行结果:


    范例七:转换部分指定列名
    R语言

    library(RODBC)
    channel <- odbcConnect("tsodbc")
    sqlstr <- '
    SetSysParam("BegT",20240115t);
    SetSysParam("EndT",20240116t);
    t := QueryWithPeriod("","SH000001",@True,"","最高价",@high(),
      "最低价",@low(),
      "涨幅(%)",@StockZf3(),
      "收盘价",@close(),
      "开盘价",@open(),
      "成交量",@vol(),
      "成交金额",@amount(),
      "成交比数",@tradecount());
    //模型中默认返回两个中文名称列,需要转换
    reindex(t,nil,array(Utf8ToAnsi("代码"):"代码",Utf8ToAnsi("名称"):"名称"));
    t ::= ifstring(mcell) ? ansitoutf8(mcell) : mcell;
    return t;'
    xxx <- sqlQuery(channel,sqlstr)
    print(xxx)
    执行结果: