【问题标题】:R - Converting Fractions in Text to NumericR - 将文本中的分数转换为数字
【发布时间】:2015-02-22 21:13:12
【问题描述】:

例如,我正在尝试将 '9¼"' 转换为 '9.25',但似乎无法正确读取分数。

这是我正在处理的数据:

library(XML)

url <- paste("http://mockdraftable.com/players/2014/", sep = "")  
combine <- readHTMLTable(url,which=1, header=FALSE, stringsAsFactors=F)

names(combine) <- c("Name", "Pos", "Hght", "Wght", "Arms", "Hands",
                    "Dash40yd", "Dash20yd", "Dash10yd", "Bench", "Vert", "Broad", 
                    "Cone3", "ShortShuttle20")

例如,第一行的 Hands 列是 '9¼"',我怎样才能让 combine$Hands 变成 9.25?对于所有其他分数 1/8 - 7/8 都是一样的。

任何帮助将不胜感激。

【问题讨论】:

标签: r string


【解决方案1】:

您可以尝试在使用特殊返回函数读取 XML 时直接将 unicode 编码转换为 ASCII:

library(stringi)
readHTMLTable(url,which=1, header=FALSE, stringsAsFactors=F,elFun=function(node) {
        val = xmlValue(node); stri_trans_general(val,"latin-ascii")})

然后您可以使用@Metrics 的建议将其转换为数字。

例如,您可以使用@G。来自this post 的格洛腾迪克函数清理Arms 数据:

library(XML)
library(stringi)
library(gsubfn)
#the calc function is by @G. Grothendieck
calc <- function(s) {
        x <- c(if (length(s) == 2) 0, as.numeric(s), 0:1)
        x[1] + x[2] / x[3]
}

url <- paste("http://mockdraftable.com/players/2014/", sep = "")  

combine<-readHTMLTable(url,which=1, header=FALSE, stringsAsFactors=F,elFun=function(node) {
        val = xmlValue(node); stri_trans_general(val,"latin-ascii")})

names(combine) <- c("Name", "Pos", "Hght", "Wght", "Arms", "Hands",
                    "Dash40yd", "Dash20yd", "Dash10yd", "Bench", "Vert", "Broad", 
                    "Cone3", "ShortShuttle20")

sapply(strapplyc(gsub('\"',"",combine$Arms), "\\d+"), calc)

#[1] 30.000 31.500 30.000 31.750 31.875 29.875 31.000 31.000 30.250 33.000 32.500 31.625 32.875

可能存在一些编码问题,具体取决于您的机器(请参阅 cmets)

【讨论】:

  • 这很有趣,但是(至少在我的 Windows 7 计算机上)不能正确读取所有分数。 Travis Carrie(例如),排在第 5 位的球员,其手臂为 31 7/8",但读取为 31a...z"。看起来可能 1/4、1/2 和 3/4 被正确翻译,但不是 1/8 的奇数倍的分数。
  • 奇怪,我在 MacOS 上,1/8 转换得很好,也许stri 的另一个功能可以在这里使用,感谢添加library
  • 认为这可能是操作系统问题。我从来没有机会(或理由)真正弄清楚我的 Windows 机器上的编码。我只是注意到每当我尝试与他们一起尝试时,他们似乎并没有得到特别好的处理......
  • @NicE 成功了。显然问题是编码。谢谢大家。
【解决方案2】:

我认为这与替代方案相比并不聪明或高效,但它使用 gsub 替换 " 符号并将每个分数转换为其小数,然后再转换为数字:

#data (I've not downloaded XML for this, so maybe the encoding will make a difference?)
combine = data.frame(Hands = c('1"','1⅛"','1¼"','1⅜"','1½"','1⅝"','1¾"','1⅞"'))

#remove the "
combine$Hands = gsub('"', '', combine$Hands)

#replace each fraction with its decimal form
combine$Hands = gsub("⅛", ".125", combine$Hands)
combine$Hands = gsub("¼", ".25", combine$Hands)
combine$Hands = gsub("⅜", ".375", combine$Hands)
combine$Hands = gsub("½", ".5", combine$Hands)
combine$Hands = gsub("⅝", ".625", combine$Hands)
combine$Hands = gsub("¾", ".75", combine$Hands)
combine$Hands = gsub("⅞", ".875", combine$Hands)


combine$Hands <- as.numeric(combine$Hands)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多