【问题标题】:Type conversion in F#F# 中的类型转换
【发布时间】:2013-09-10 20:57:53
【问题描述】:

我通过 F# 脚本将 excel 数据导入到 R 回归中使用。代码是:

let path = @"C:\Data\DataForRegression.csv"
let fileStream = new FileStream(path,FileMode.Open,FileAccess.Read)
let streamReader = new StreamReader(fileStream)
let contents = streamReader.ReadToEnd()

let cleanContents =
    contents.Split([|'\n'|])
    |> Seq.map(fun line -> line.Split([|','|]))
    |> Seq.skip(1)
    |> Seq.map(fun values ->
        Double.Parse(values.[0]),
        Double.Parse(values.[1]),
        DateTime.Parse(values.[2]).ToShortDateString(),
        Int32.Parse(values.[3]),
        Int32.Parse(values.[4]),
        Int32.Parse(values.[5]),
        Int32.Parse(values.[6]))

//open R
let environmentPath = System.Environment.GetEnvironmentVariable("PATH")
let binaryPath = @"C:\Program Files\R\R-3.0.1\bin\x64"
System.Environment.SetEnvironmentVariable("PATH",environmentPath+System.IO.Path.PathSeparator.ToString()+binaryPath)

let engine = RDotNet.REngine.CreateInstance("RDotNet")
engine.Initialize()

let pmpm = engine.CreateNumericVector(cleanContents |> Seq.map (fun (a,b,c,d,e,f,g) -> a))
engine.SetSymbol("pmpm",pmpm)

第一行数据如下:

$66.92,0.9458,Jan-13,0,0,0,1

当我运行它时,我得到了这个:

System.FormatException:输入字符串的格式不正确。
在 System.Number.ParseDouble(字符串值,NumberStyles 选项, NumberFormatInfo numfmt) 在 FSI_0002.cleanContents@18.Invoke(String[] values) 在 C:\TFS\Tff.RDotNetExample_Solution\Tff.RDotNetExample\RegressionUsingExcelImport.fsx:line 19 在 Microsoft.FSharp.Collections.IEnumerator.map@109.DoMoveNext(b&) 在 Microsoft.FSharp.Collections.IEnumerator.MapEnumerator1.System-Collections-IEnumerator-MoveNext() at Microsoft.FSharp.Collections.IEnumerator.map@109.DoMoveNext(b& )
at Microsoft.FSharp.Collections.IEnumerator.MapEnumerator
1.System-Collections-IEnumerator-MoveNext() 在 System.Linq.Enumerable.Count[TSource](IEnumerable1 source) at RDotNet.Vector1..ctor(REngine 引擎,SymbolicExpressionType 类型, IEnumerable1 vector) at RDotNet.NumericVector..ctor(REngine engine, IEnumerable1 向量)在 RDotNet.REngineExtension.CreateNumericVector(REngine 引擎, IEnumerable`1 向量)在 .$FSI_0002.main@() 在 C:\TFS\Tff.RDotNetExample_Solution\Tff.RDotNetExample\RegressionUsingExcelImport.fsx:line 35 因错误而停止

有人知道我需要做什么来转换数据吗?我的预感是它不喜欢 '$' - 但它加载到 Double.Parse 中没有问题(除非它没有被评估?)。

提前致谢

【问题讨论】:

  • 嘿,实际数据的第一行是什么(假设您没有尝试将“PMPM”的文本值解析为双精度值)...

标签: r f#


【解决方案1】:

使用以下内容:

Double.Parse(values.[0], NumberStyles.AllowDecimalPoint ||| NumberStyles.AllowCurrencySymbol, CultureInfo("en-US"))

http://msdn.microsoft.com/en-us/library/fd84bdyt.aspx:

使用 NumberStyles.Float 和 NumberStyles.AllowThousands 标志的组合来解释 s 参数。这意味着允许使用空格和千位分隔符,例如,不允许使用货币符号。为了更好地控制 s 中允许哪些样式元素以使解析操作成功,请调用 Double.Parse(String, NumberStyles) 或 Double.Parse(String, NumberStyles, IFormatProvider) 方法。

因此,即使您的默认文化已经是具有$ 作为货币符号的文化,您仍然必须明确使用NumberStyles.AllowCurrencySymbol

【讨论】:

    【解决方案2】:

    尝试将 Double.Parse(values.[0]) 更改为 Double.Parse(values.[0].Remove(0,1)) 以删除美元符号。

    【讨论】:

    • 关于评估...在您声明 cleanContents 后,cleanContents 评估为 seq<float * float * string * int * int * int * int>。我的印象是,由于其中包含 lambda,因此在最终在 engine.SetSymbol("pmpm",pmpm) 使用之前,它不会评估为 seq [(66.92, 0.9458, "1/13/2013", 0, 0, 0, 1)]
    猜你喜欢
    • 2019-09-15
    • 2017-02-20
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    相关资源
    最近更新 更多