【问题标题】:Applying round function to every element in a dataframe将舍入函数应用于数据框中的每个元素
【发布时间】:2017-01-07 05:02:43
【问题描述】:

假设我在 R 中有一个这样的数据框

x = c(2, 3.432, 5)
y = c(4.5345, NA, "text")
z = c(8.13451, 3.12451, 6.12341)
A = data.frame(x, y, z)

如何将 round 函数应用于数据框的适当元素? 基本上我想:

  • 检查元素是否为数字
  • 如果没有,请不要进行任何更改
  • 如果是数字,则将其四舍五入到小数点后 3 位

我在很多地方读到循环在 R 中不是一个好主意。尝试像这样的行

A$y[is.numeric(A$y)] <- round(A$y, digits = 3)

没用

【问题讨论】:

    标签: r loops


    【解决方案1】:

    我们可以试试lapply

    A[] <- lapply(A, function(x) if(is.numeric(x)) round(x, 3) else x)
    

    如果我们还需要更改具有character/factor 类列的数字元素的格式

    A[] <- lapply(A, function(x) {
               x1 <- type.convert(as.character(x), as.is=TRUE)
        ifelse(grepl("^[0-9.]+$", x1), round(as.numeric(x1), 3), x1)})
    

    【讨论】:

    • 谢谢!所以本质上你是把它们变成字符并使用正则表达式检查它们是否包含数字
    • @Shekar 是的,你是对的。 type.convert 会将其转换为它应该自然发生的类,然后使用 grepl 我们确保它是所有数字,然后是 round 它或者保持原样
    【解决方案2】:

    你对循环有正确的想法。正如@jennybryan 所说:“当然有人必须编写循环。不一定是你。”

    按照@akrun 的建议,将 lapply 与 ifelse 一起使用是一种方法。 使用 dplyr 处理数据帧是另一种方式,它是包和函数“tidyverse”的一部分,这些包和函数具有一致的语法并且在其名称中具有描述性(更冗长但可以说值得)。

    按照你的问题去做,

    x = c(2, 3.432, 5)
    y = c(4.5345, NA, "text")
    z = c(8.13451, 3.12451, 6.12341)
    A = data.frame(x, y, z)
    library(dplyr)
    mutate(A, across(where(is.numeric), round, 3))
    #>       x      y     z
    #> 1 2.000 4.5345 8.135
    #> 2 3.432   <NA> 3.125
    #> 3 5.000   text 6.123
    
    # can also be written as
    # A %>% mutate(across(where(is.numeric), round, 3))
    

    reprex package (v0.3.0) 于 2020 年 10 月 29 日创建

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-13
      • 2020-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-09
      相关资源
      最近更新 更多