【问题标题】:Remove string character from multiple columns in R and mutate从 R 中的多个列中删除字符串字符并进行变异
【发布时间】:2021-05-23 15:50:34
【问题描述】:

这是我的数据框(tables_df)的头部,都是字符类型:

#        Name Ticker  Last price       %     %7d    %30d    %90d    %180d    %365d # Coins
1 1     bitcoin    BTC $ 56,667.17   1.33%  21.13%  74.43% 209.62%  386.02%  489.33%  18.63M
2 2    ethereum    ETH $ 1,976.941   1.00%  10.37%  60.49% 269.53%  404.93%  662.55% 114.75M
3 3 binancecoin    BNB $ 265.20462 -20.41% 102.40% 553.29% 791.32% 1114.70% 1083.61%  99.01M
4 4     cardano    ADA $ 1.1537436  24.50%  31.18% 239.85% 765.91%  849.66% 1909.86%  25.92B
5 5    litecoin    LTC $ 231.95832  -2.28%   4.65%  72.05% 180.01%  282.54%  227.14%  66.08M
6 6     uniswap    UNI $ 30.304469  50.48%  41.73% 268.43% 732.38%       0%       0% 126.20M
  Market cap MC rank
1    $ 1.05T       1
2  $ 226.86B       2
3   $ 26.25B       5
4   $ 29.91B       4
5   $ 15.32B       7
6    $ 3.82B      23

我想在 R 中做 3 件事

  1. 将列名中包含“%”的所有列中的百分比字符转换为数字百分比值
  2. 将具有 M(百万)或 B(十亿)或 T(万亿)的字符转换为“Marcet cap”和“Coins”列中的数值(x1000.000 表示百万,x1.000.000.000 表示十亿和 x1。 000.000.000.000 表示万亿)
  3. 删除美元符号并将“最后价格”和“市值”列中的数字转换为数字

第一件事我尝试了这段代码:

tables_df %>% mutate_at(vars(contains('%')), str_remove(string = .,pattern = "%")) %>%
  mutate_at(vars(contains('%')),funs =  as.numeric())

还有这段代码:

tables_df %>% parse_number("%", trim_ws = TRUE)

很遗憾,这两种尝试都不起作用。

对于我的第二和第三件事,我还没想好从哪里开始。有人可以帮我吗?非常感谢!

dput(head(tables_df))
structure(list(`#` = c("1", "2", "3", "4", "5", "6"), c("", "", 
"", "", "", ""), Name = c("bitcoin", "ethereum", "binancecoin", 
"cardano", "litecoin", "uniswap"), Ticker = c("BTC", "ETH", "BNB", 
"ADA", "LTC", "UNI"), `Last price` = c("$ 57,431.62", "$ 1,959.472", 
"$ 302.91449", "$ 1.1072817", "$ 230.71046", "$ 29.981031"), 
    `%` = c("2.59%", "2.21%", "19.01%", "-0.96%", "1.50%", "4.01%"
    ), `%7d` = c("17.24%", "7.72%", "123.90%", "32.27%", "5.13%", 
    "38.44%"), `%30d` = c("80.95%", "63.35%", "648.16%", "234.17%", 
    "66.21%", "259.22%"), `%90d` = c("211.37%", "236.87%", "893.12%", 
    "617.17%", "165.07%", "688.65%"), `%180d` = c("388.06%", 
    "379.98%", "1238.50%", "793.63%", "271.27%", "0%"), `%365d` = c("496.72%", 
    "658.28%", "1263.44%", "1798.47%", "231.57%", "0%"), `# Coins` = c("18.63M", 
    "114.76M", "99.01M", "25.92B", "66.08M", "126.20M"), `Market cap` = c("$ 1.07T", 
    "$ 224.87B", "$ 29.99B", "$ 28.70B", "$ 15.24B", "$ 3.78B"
    ), `MC rank` = c("1", "2", "4", "5", "7", "23")), row.names = c(NA, 
6L), class = "data.frame")

【问题讨论】:

    标签: r


    【解决方案1】:

    编写一个函数将百万/十亿/万亿更改为实际数字。

    change_num <- function(x) {
      x1 <- parse_number(x)
      x1 * case_when(grepl('T', x) ~ 1e12, 
                     grepl('B', x) ~ 1e9, 
                     grepl('M', x) ~ 1e6)
    }
    

    使用across 将函数应用于多个列。

    library(dplyr)
    library(readr)
    
    tables_df <- tables_df[-2] %>%
                    mutate(across(`Last price`:`%365d`, parse_number),
                      across(c(`# Coins`,`Market cap`), change_num))
    
    tables_df
    
    #           Name Ticker   Last price     %    %7d   %30d   %90d   %180d   %365d
    #1 1     bitcoin    BTC 57431.620000  2.59  17.24  80.95 211.37  388.06  496.72
    #2 2    ethereum    ETH  1959.472000  2.21   7.72  63.35 236.87  379.98  658.28
    #3 3 binancecoin    BNB   302.914490 19.01 123.90 648.16 893.12 1238.50 1263.44
    #4 4     cardano    ADA     1.107282 -0.96  32.27 234.17 617.17  793.63 1798.47
    #5 5    litecoin    LTC   230.710460  1.50   5.13  66.21 165.07  271.27  231.57
    #6 6     uniswap    UNI    29.981031  4.01  38.44 259.22 688.65    0.00    0.00
    
    #     # Coins Market cap MC rank
    #1 1.8630e+07 1.0700e+12       1
    #2 1.1476e+08 2.2487e+11       2
    #3 9.9010e+07 2.9990e+10       4
    #4 2.5920e+10 2.8700e+10       5
    #5 6.6080e+07 1.5240e+10       7
    #6 1.2620e+08 3.7800e+09      23
    

    【讨论】:

    • 非常感谢!不幸的是,我不断收到此错误: > tables_df %>% + mutate(across(c("Last price" : "%365d"), parse_number), + cross(c("# Coins", "Market cap"), change_num )) 初始化错误(...):尝试使用零长度变量名
    • 试过这个:tables_df %>% mutate(across("Last price" : "%365d", parse_number), cross(c("# Coins", "Market cap"), change_num)) --> 但仍然收到相同的错误消息。我使用 dput(colnames(tables_df)) 函数复制并粘贴的列名,因此它们的拼写完全正确。
    • @A.Jackson 你能用dput(head(tables_df)) 编辑你的帖子,以便我得到你的数据的可复制粘贴版本。
    • 是的,我刚刚添加了,希望对您有所帮助
    • 数据中的第二列是空的,没有列名,因此您会收到错误消息。列名也不是 R 的标准列名,因此很难引用它们。通常最好提前执行一些数据清理以避免此类错误。您现在可以尝试更新的答案。
    猜你喜欢
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    • 2018-03-16
    • 2013-08-20
    • 2023-01-11
    相关资源
    最近更新 更多