R -使用mutate分配类

ggazkfy8  于 2023-06-19  发布在  其他
关注(0)|答案(3)|浏览(101)

我正在使用openxlsx包创建excel文件。要将列格式化为美元,示例中说要将类设置为'currency':

class(df$Currency) <- 'currency'

但是,我想将此应用于许多列,如一次,并重复一次货币,一次百分比等。这是我的最终目标,无论我如何到达那里--这是我迄今为止所做的尝试。
首先是工作示例:

df <- data.frame(sales = c(10, 20, 30, 40, 50), returns = c(-5, -10, -20, 0, 0))
class(df$sales) <- 'currency'
class(df$sales)
[1] "currency"

现在使用dplyr和mutate尝试1:

df %>% 
mutate_all(`class<-`(., 'currency'))
Error: Can't create call to non-callable object

尝试2:

df <- df %>% 
`class<-`(., 'currency') 
df
$sales
[1] 10 20 30 40 50
attr(,"class")
[1] "currency"

这更接近我想要的,但输出是一个列表,as.data.frame和as.tbl都抱怨类'currency'没有方法。
当我使用类(df$sales)<- 'currency'时,我可以在现有的dataframe中更改类。
我感觉这是一个学习更多关于类的好机会(我复习了关于类的高级R部分,但无法与我的问题联系起来)

nfs0ujit

nfs0ujit1#

回应@Frank的评论:

as.currency <- function(x) {class(x) <- "currency"; x}

iris %>%   
  mutate_all(funs(as.currency(.))) %>% 
  glimpse()
Observations: 150
Variables: 5
$ Sepal.Length <S3: currency> 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9, 5.4, 4.8, 4.8, 4.3, 5.8, 5.7, 5.4, 5.1, 5.7, 5.1, ...
$ Sepal.Width  <S3: currency> 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3.0, 3.0, 4.0, 4.4, 3.9, 3.5, 3.8, 3.8, ...
$ Petal.Length <S3: currency> 1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.6, 1.4, 1.1, 1.2, 1.5, 1.3, 1.4, 1.7, 1.5, ...
$ Petal.Width  <S3: currency> 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, ...
$ Species      <S3: currency> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1...
jrcvhitl

jrcvhitl2#

可以使用purrr,但是只有当每个列也从numeric继承时(即同时是货币和数字),结果才能被强制转换为 Dataframe 。我不知道这对openxlsx是否足够好。

dfr <- data.frame(x=1:10, y=1:10, z=1:10)
library(purrr)
as.data.frame(map(dfr, `class<-`, c("currency","numeric")))

给予

sapply(x, class)
     x          y          z         
[1,] "currency" "currency" "currency"
[2,] "numeric"  "numeric"  "numeric"
thigvfpy

thigvfpy3#

我不知道如何使用dplyr做到这一点,但这里有一个工作的方法。

# list the column names
names <- colnames(df)

# loop through the columns and assign the class 'currency'
for (i in 1:length(names)){

  class(df[, names[i]])  <- 'currency'
}

lapply(df, class)
$sales
[1] "currency"

$returns
[1] "currency"

相关问题