我有一个来自REGIS的数据表,其中包括随机列中的数字金额,这些数字金额由"$1.11 M"(例如)而不是1,110,000.00作为数字汇总。在这些随机列中,它可以显示为"M"或"B"或"K"(表示百万、数十亿或数千)。
我正在尝试找出一个代码,该代码将找到并删除"$"和"M",然后将数字乘以 1,000,000(或任何美元金额应该是多少)。
我试过使用lapply
、if_else
、Gsub
...但我无法弄清楚如何仅对具有字符"$"和"M"(或"B"、"K")的单元格进行这些更改
到目前为止,我有:
df1$1<-sapply(gsubfn("[A-Z]", list(K = "*1000", M = "*1e6", B = "*1e9"),
sub("$", "",df1$1, fixed = TRUE)), function(x) eval(parse(text = x)))
问题是我正在寻找一种方法来使此代码一次覆盖我的所有列......而不是特定的列。
我希望(例如)将"$1.65 K"更改为 1,650.00 或"3.96 M"更改为 3,960,000.00
我们可以使用gsubfn
通过传递键/值list
将"M"、"K"值替换为乘数字符串,然后eval
使用字符串并将其更改为自定义格式,dollar_format
来自scales
library(gsubfn)
library(scales)
out <- sapply(gsubfn("[A-Z]", list(K = "*1000", M = "*1e6"),
sub("$", "", str1, fixed = TRUE)), function(x) eval(parse(text = x)))
dollar_format()(out)
#[1] "$1,650" "$3,960,000"
如果我们需要更改所有列
df1[] <-lapply(df1, function(x) dollar_format()(sapply(gsubfn("[A-Z]",
list(K = "*1000", M = "*1e6", B = "*1e9"),
sub("$", "", x, fixed = TRUE)), function(y) eval(parse(text = y)))))
更新
OP想出了更多的模式。 为此,我们可以做
df2[] <- lapply(df2, function(x) {
i1 <- grepl("[KMB]", x) # create index to change only those have KMB
x[i1] <- dollar_format()(
sapply(gsubfn("[A-Z]", list(K = "*1000", M = "*1e6", B = "*1e9"),
sub("$", "", x[i1], fixed = TRUE)),
function(y) eval(parse(text = y))))
x
})
df2
# col1 col2
#1 $1,650 $1,650
#2 $3,960,000 $3,960,000
#3 $-1,650 $-1,650
#4 -950 -950
数据
str1 <- c("$1.65 K" , "3.96 M")
df1 <- data.frame(col1 = str1, col2 = str1, stringsAsFactors = FALSE)
str2 <- c("$1.65 K" , "3.96 M", "-$1.65 K", "-950")
df2 <- data.frame(col1 = str2, col2 = str2, stringsAsFactors = FALSE)