如何将 sprintf 函数应用于 r 数据框以将值转换为百分比,同时保持原始数据框结构?

How to apply sprintf function to r data frame to convert values to percentages while maintaining original data frame structure?

我正在研究用于格式化数据框中所有数值的选项,而不仅仅是选定的列。当 运行 下面的代码时,我从以下称为“c”的基本数据框开始:

> c
        A        B
1 3.412324 2.234200
2 3.245236 4.234234
    
Related code:
a <- c(3.412324463,3.2452364)
b <- c(2.2342,4.234234)
c <- data.frame(A=a, B=b, stringsAsFactors = FALSE)

接下来,我将上述“c”数据框中的所有数字四舍五入到小数点后 2 位,得到如下所示的数据框“d”,并在下方显示相关代码:

 > d
         A    B
 [1,] 3.41 2.23
 [2,] 3.25 4.23
        
 Related code:
 d <- as.data.frame(lapply(c, formatC, decimal.mark =".", format = "f", digits = 2))
 d <- sapply(d[,],as.numeric)

最后一步,我想在一个名为“e”的新数据框中以百分比表示上述数据框“d”。我使用下面显示的代码得到以下结果列表。

> e
   X.341.0.. X.325.0.. X.223.0.. X.423.0..
1    341.0%    325.0%    223.0%    423.0%
    
Related code:
e <- as.data.frame(lapply(d*100, sprintf, fmt = "%.1f%%"))

如何以有效的方式修改代码,以便在导出数据帧“e”时保持数据帧结构完整,就像生成数据帧“d”时那样?在 base R 和 dplyr.

中看到解决方案将是最有帮助的

我很确定问题出在我使用 lapply() 创建数据框“e”(是的,现在我知道 lapply() 吐出列表),但它工作正常在创建数据框“d”时维护数据框结构!

数据框中的所有值都采用相同的格式,因此无需对列等进行子集化。

lapply 的问题在于它 returns 一个 listdata.frame 是列表的特例,但要使 lapply 修改特定结构的数据框同时保持该结构,最简单的方法是 df[] = lapply(df, ...)。额外的 [] 保留现有结构。

## d better base version
## `round` is friendlier than `sprintf` - it returns numerics
d = c
d[] = lapply(d, round, 2)
d 
#      A    B
# 1 3.41 2.23
# 2 3.25 4.23

## dplyr version
d_dplyr = c %>%
  mutate(across(everything(), round, 2))
d_dplyr
#      A    B
# 1 3.41 2.23
# 2 3.25 4.23

## e base
e = d
e[] = lapply(e * 100, sprintf, fmt = "%.1f%%")
e
#        A      B
# 1 341.0% 223.0%
# 2 325.0% 423.0%

## e dplyr
## in `tidyverse`, we'll use `scales::percent_format` 
## which generates a percent conversion function according to specification
## the default already multiplies by 100 and adds the `%` sign
## we just need to specify the accuracy.
## (note that we can easily start from `c` again)
e_dplyr = c %>%
  mutate(across(everything(), scales::percent_format(accuracy = 0.1)))
e_dplyr
#        A      B
# 1 341.2% 223.4%
# 2 324.5% 423.4%