R - 使用mutate分配类

问题描述:

我正在使用openxlsx包创建excel文件。要格式化列美元,例子说给类设置为“货币”:R - 使用mutate分配类

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和变异 尝试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都抱怨没有方法等级为“货币”。

当我使用类(df $ sales)< - '货币'时,我可以在现有数据框中更改类。

我有一种感觉,这是一个很好的机会,以了解更多关于类(我审查了关于类的高级R段,但不能让我的问题的连接)

+1

定义'as.currency'和使用? – Frank

+0

谢谢弗兰克 - 我很早就试过了,放弃得太快了 - 以下面提供的例子为例,返回函数中的x正是我所需要的。 – Davidws

为了呼应@以上弗兰克的评论:

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... 
+0

谢谢!我很早就尝试过,但没有返回x。结合变异这个作品。我希望我可以创建一个函数为我想要的格式列表创建这些函数,并使用这种方法应用每个函数。 – Davidws

我不知道如何做到这一点使用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" 

它可以使用purrr,但其结果只能强制转换为数据帧,如果每列也从numeric继承(即,既是货币和数字)。我不知道这对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" 
+0

谢谢,我甚至没有想过用purrr一次做所有事情。我会看看openxlsx是否接受这个,但即使不是很好的方法。 – Davidws