【问题标题】:Divide column by 1000 if maximum exceed certain limit如果最大值超过特定限制,则将列除以 1000
【发布时间】:2021-07-02 07:03:49
【问题描述】:

我想编写一个非常简单的程序:它应该遍历数据框中的所有列,如果至少有一个大于 1000 的观察值,那么程序应该将此变量除以 1000,并将"in (000)" 添加到变量名中。

我的解决方案

set.seed(42)
df <- data.frame("Norm" = rnorm(100, 1000, 0.1), rexp(100))

for (var in seq_len(ncol(df))) {
  if (max(df[, var], na.rm = T) > 1000) {
    df[, var] <- df[, var] / 1000
    colnames(df)[var] <- print(paste(colnames(df[var]), "(in 000')"))
  }
}

但是我觉得这有点不方便。我认为这里不需要循环。我尝试使用 apply 来做到这一点,但我不确定为什么我获得的列最大值除以 1000 而不是每个值除以 1000 的数据框:

apply(df, 2, function(x) ifelse(max(x) > 1000, x/1000, x))

 Norm rexp.100. 
0.9999925 0.4473922

你知道如何在没有循环的情况下完成吗?

【问题讨论】:

    标签: r dataframe loops apply


    【解决方案1】:

    apply 用于矩阵,不要在数据帧上使用它。 ifelse 用于向量测试 - 输出与输入的形状相同。您对ifelse() 的输入是长度为1 的max(x) &gt; 1000,因此结果将是长度1。您可以使用lapply 代替for 和if(){}else{} 而不是ifelse():

    df[] <- lapply(df, function(x) if(max(x, na.rm = TRUE) > 1000) {x / 1000}else{x})
    

    但是使用 *apply 系列函数,您必须返回并在另一个步骤中更改名称 --- 在这种情况下,我通常更喜欢 for。

    但我可能会这样做而不循环:

    cols_over_1000 = sapply(df, max, na.rm = TRUE) > 1000
    df[cols_over_1000] = df[cols_over_1000] / 1000
    names(df)[cols_over_1000] = paste(names(df)[cols_over_1000], "(in '000)")
    

    或者在dplyr:

    library(dplyr)
    df %>%
      mutate(across(
        where(~ any(. > 1000)),
        ~ . / 1000,
        .names = "{.col} (in '000)"
      ))
    

    【讨论】:

      【解决方案2】:
      ab1k <- sapply(df, function(x) any(x > 1000))
      df[ab1k] <- df[ab1k]/1000
      names(df)[ab1k] <- paste(names(df)[ab1k], "(in 000')")
      

      【讨论】:

        【解决方案3】:

        您可以尝试像这样使用purrr 包:

        library(dplyr)
        library(purrr)
        
        my_fun <- function(x,y){
              if(max(x, na.rm = T)>1000){
                    return(rename_with(tibble(x/1000),~paste0(y,"(in '000)")))
              }else{return(rename_with(tibble(x),~y))}
        }
        
        map2_dfc(df,names(df),my_fun)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-12-26
          • 2018-12-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-04
          • 2017-07-31
          • 1970-01-01
          相关资源
          最近更新 更多