【问题标题】:extract a labelled number from a character string从字符串中提取带标签的数字
【发布时间】:2018-04-23 12:14:41
【问题描述】:

我在数据框中有一个向量,它在记录时以 eur、gbp 和 usd 列出价格。数据在一个条目中列出了所有三个值,例如:

X<-c( "{\"eur\": 4900, \"gbp\": 4250, \"usd\": 6120}", 
                 "{\"gbp\": 730, \"usd\": 1050}",  
                 "{\"eur\": 1050, \"gbp\": 910, \"usd\": 1310}",
                 "{\"eur\": 400, \"gbp\": 350, \"usd\": 500}" )
X
    [1] "{\"eur\": 4900, \"gbp\": 4250, \"usd\": 6120}"
    [2] "{\"gbp\": 730, \"usd\": 1050}"                
    [3] "{\"eur\": 1050, \"gbp\": 910, \"usd\": 1310}" 
    [4] "{\"eur\": 400, \"gbp\": 350, \"usd\": 500}" 

所以一个条目看起来像{"eur": 8200, "gbp": 6740, "usd": 9600}

大多数条目都有 eur、gbp 和 usd 的值,但有些条目缺少一种货币的数据,例如 {"gbp": 9700, "usd": 13650}

我认为将其作为一个列表或 3 个单独的向量可能更有意义,但当我从 csv 导入数据时,它作为一个字符出现。

我想要的是从字符串中提取 GBP 值,所以对于price: {"eur": 12100, "gbp": 10200, "usd": 14500},我会得到priceGBP: 10200

我想我可以做一些过于复杂和模糊的事情来得到这个,例如使用 grep 在字符串中查找“gbp”的位置,然后提取它后面的字符。但我想知道考虑到数据的结构,是否有一种巧妙的方法可以做到这一点。

我可以用其他方式导入 csv 吗?

【问题讨论】:

标签: r


【解决方案1】:

如果我正确理解了你的问题,那么你可以试试这个 -

library(dplyr)

df %>%
  mutate(priceGBP=ifelse(grepl("gbp", price), 
                         gsub(".*\"gbp\": (\\d+).*", "\\1", price), 
                         NA))

输出为:

                                    price priceGBP
1 {"eur": 4900, "gbp": 4250, "usd": 6120}     4250
2               {"gbp": 730, "usd": 1050}      730
3               {"eur": 1050,"usd": 1310}     <NA>
4    {"eur": 400, "gbp": 350, "usd": 500}      350

样本数据:

df <- structure(list(price = structure(c(3L, 4L, 1L, 2L), .Label = c("{\"eur\": 1050,\"usd\": 1310}", 
"{\"eur\": 400, \"gbp\": 350, \"usd\": 500}", "{\"eur\": 4900, \"gbp\": 4250, \"usd\": 6120}", 
"{\"gbp\": 730, \"usd\": 1050}"), class = "factor")), .Names = "price", row.names = c(NA, 
-4L), class = "data.frame")

【讨论】:

  • 谢谢,效果很好!我现在将阅读更多关于 mutate 和正则表达式的内容。
  • 太棒了!很高兴它有帮助。
【解决方案2】:

您可以尝试tidyverse 方法

library(tidyverse)
str_split(X, pattern = ",") %>% 
   map(.,~grep("gbp", ., value=T)) %>%   
   map_chr(.,~str_split(.,":", simplify = T)[2] %>% str_trim) %>% 
   as.numeric()
[1] 4250  730  910  350

【讨论】:

  • 感谢 Jimbou,我已经编辑了我的问题以包含示例数据。我的数据不在列表中,但我已使用 stringr 将其放入类似于您的示例的列表中。但是当我尝试运行您的代码时,我得到了 gbp 条目的索引,而不是 gbp 值:[1] 2 2 1。我认为我的问题出在 map_chr 上?
  • 我希望现在已经清楚了。这是我关于堆栈溢出的第一个问题,我的格式有点混乱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
  • 2014-10-09
  • 1970-01-01
  • 2019-12-13
  • 1970-01-01
相关资源
最近更新 更多