代码之家  ›  专栏  ›  技术社区  ›  sbac

如何在R中动态地改变数据帧中的列

  •  1
  • sbac  · 技术社区  · 5 年前

    我想改变a的值 dataframe tibble 列定义为变量( col_name ).我试过了 !!col_name 没有成功。

    library(dplyr)
    #> 
    #> Attaching package: 'dplyr'
    #> The following objects are masked from 'package:stats':
    #> 
    #>     filter, lag
    #> The following objects are masked from 'package:base':
    #> 
    #>     intersect, setdiff, setequal, union
    col_name <- "b" # the column to select
    
    df <- tibble(a = c(1,2,3), b = c(2,4,6))
    
    df %>%
      mutate(b = if_else((b == 6 & a == 3), 8, b))  # this works 
    #> # A tibble: 3 x 2
    #>       a     b
    #>   <dbl> <dbl>
    #> 1     1     2
    #> 2     2     4
    #> 3     3     8
    
    # but this doesn't
    df %>%
      mutate(!!col_name := if_else((!!col_name == 6 & a == 3), 8, !!col_name))
    #> Error: Problem with `mutate()` input `b`.
    #> x `false` must be a double vector, not a character vector.
    #> i Input `b` is `if_else(("b" == 6 & a == 3), 8, "b")`.
    Created on 2020-10-13 by the reprex package (v0.3.0)
    
    1 回复  |  直到 5 年前
        1
  •  3
  •   zx8754    5 年前

    使用 :

    df[ df[, col_name ] == 6 & df$a == 3, col_name ] <- 8
    
    df
    #   a b
    # 1 1 2
    # 2 2 4
    # 3 3 8
    

    是的,我知道这个问题是关于 “整洁” ,这只是为了说明为什么对于一些简单的任务,基本解决方案同样好/更好。

        2
  •  2
  •   zx8754    5 年前

    !! 在RHS上,您需要首先转换 col_name 去象征。

    library(dplyr)
    df %>% mutate(!!col_name := if_else(!!sym(col_name) == 6 & a == 3, 
                                8, !!sym(col_name)))
    

    其他选择包括使用 get

    df %>% mutate(!!col_name := if_else(get(col_name) == 6 & a == 3,
                                 8, get(col_name)))
    

    或者不使用任何NSE .data :

    df %>% mutate(!!col_name := if_else(.data[[col_name]] == 6 & a == 3, 
                                8, .data[[col_name]]))