如何使用dplyr :: mutate_all对选定的列进行四舍五入

47

我正在使用以下软件包版本

# devtools::install_github("hadley/dplyr")
> packageVersion("dplyr")
[1] ‘0.5.0.9001’

使用以下数据表:

library(dplyr)
df  <- structure(list(gene_symbol = structure(1:6, .Label = c("0610005C13Rik", 
"0610007P14Rik", "0610009B22Rik", "0610009L18Rik", "0610009O20Rik", 
"0610010B08Rik"), class = "factor"), fold_change = c(1.54037, 
1.10976, 0.785, 0.79852, 0.91615, 0.87931), pvalue = c(0.5312, 
0.00033, 0, 0.00011, 0.00387, 0.01455), ctr.mean_exp = c(0.00583, 
59.67286, 83.2847, 6.88321, 14.67696, 1.10363), tre.mean_exp = c(0.00899, 
66.22232, 65.37819, 5.49638, 13.4463, 0.97043), ctr.cv = c(5.49291, 
0.20263, 0.17445, 0.46288, 0.2543, 0.39564), tre.cv = c(6.06505, 
0.28827, 0.33958, 0.53295, 0.26679, 0.52364)), .Names = c("gene_symbol", 
"fold_change", "pvalue", "ctr.mean_exp", "tre.mean_exp", "ctr.cv", 
"tre.cv"), row.names = c(NA, -6L), class = c("tbl_df", "tbl", 
"data.frame"))

那看起来像这样:

> df
# A tibble: 6 × 7
    gene_symbol fold_change  pvalue ctr.mean_exp tre.mean_exp  ctr.cv  tre.cv
         <fctr>       <dbl>   <dbl>        <dbl>        <dbl>   <dbl>   <dbl>
1 0610005C13Rik     1.54037 0.53120      0.00583      0.00899 5.49291 6.06505
2 0610007P14Rik     1.10976 0.00033     59.67286     66.22232 0.20263 0.28827
3 0610009B22Rik     0.78500 0.00000     83.28470     65.37819 0.17445 0.33958
4 0610009L18Rik     0.79852 0.00011      6.88321      5.49638 0.46288 0.53295
5 0610009O20Rik     0.91615 0.00387     14.67696     13.44630 0.25430 0.26679
6 0610010B08Rik     0.87931 0.01455      1.10363      0.97043 0.39564 0.52364

我想要将浮点数(从第二列开始)四舍五入到3位小数。如何使用dplyr::mutate_all()实现?

我尝试了这个:

cols <- names(df)[2:7]
# df <- df %>% mutate_each_(funs(round(.,3)), cols)
# Warning message:
#'mutate_each_' is deprecated.
# Use 'mutate_all' instead.
# See help("Deprecated") 

df <- df %>% mutate_all(funs(round(.,3)), cols)

但是出现以下错误:

Error in mutate_impl(.data, dots) : 
  3 arguments passed to 'round'which requires 1 or 2 arguments

14
这段代码的意思是,在df数据框中选择第二列到第七列,对这些列中的所有数值进行保留三位小数的四舍五入,并将结果存储回原数据框。具体实现方式是使用%>%管道符号连接mutate_atround函数。 - alistaire
@alistaire 谢谢。我该如何使用变量 cols。我尝试了这个,但出现了错误 df %>% mutate_all(cols, round, 3) - neversaint
4
df %>% mutate_at(cols, round, 3) 的意思是对于数据框 df 中指定的列 cols,进行小数点后三位的四舍五入操作(使用 dplyr 包中的函数 round),并将结果返回。由于并非针对所有列进行操作,所以使用的是 mutate_at 函数而非 mutate_all。该错误信息可能有待改进。 - alistaire
我不明白为什么 df %>% mutate_at(cols, round (.,3)) 或者 df %>% mutate_at(cols, round (.,3)) 会失败。 - Captain Tyler
1
当您在管道中使用 . 运算符时,您将左侧插入到 . 所在的位置。因此,您得到的是 round(df,3),这不是您想要的。 - Arthur Yip
2个回答

114
虽然新的`across()`函数比之前的`mutate_if`变体更冗长一些,但`dplyr 1.0.0`的更新使得tidyverse的语言和代码更加一致和多样化。
这是如何对指定列进行四舍五入的方法:
`df %>% mutate(across(2:7, round, 3))` # 按位置选择列2-7
`df %>% mutate(across(cols, round, 3))` # 按变量`cols`指定列
这是如何将所有数值列四舍五入到小数点后3位的方法:
`df %>% mutate(across(where(is.numeric), round, 3))`
这是如何对所有列进行四舍五入的方法,但在这种情况下不起作用,因为`gene_symbol`不是数值列:
`df %>% mutate(across(everything(), round, 3))`
在`across`的参数中,我们将`where(is.numeric)`放在哪里,您可以放入其他列规范,例如`-1`或`-gene_symbol`来排除第一列。有关更多选项,请参阅`help(tidyselect)`。
dplyr 1.0.0 更新 across() 函数取代了 dplyr 动词中的 _if/_all/_at/_each 变体。https://dplyr.tidyverse.org/dev/articles/colwise.html#how-do-you-convert-existing-code
旧答案: 由于某些列不是数字,您可以使用mutate_if函数,它的好处是仅在列是数字时才进行舍入操作:

df %>% mutate_if(is.numeric, round, 3)


5
你可以省略 funs 这个参数: df %>% mutate_if(is.numeric, round, 3)。该代码的作用是将 df 中所有数值型变量保留三位小数。 - JdP
1
简单明了的解决方案。但是可以使用 is.double 而不是 is.numeric,以避免转换整数变量。 - Nino
2
这对我没有用,但是 df %>% mutate(across(where(is.numeric), round, 3)) 可以。 - Chris Beeley
糟糕 - 现在已经修复了。 - Arthur Yip

7
packageVersion("dplyr")
[1] '0.7.6'

尝试

df %>% mutate_at(2:7, funs(round(., 3))) 

它可以工作啦!!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接