【问题标题】:Use map to change values使用地图更改值
【发布时间】:2021-03-14 16:13:52
【问题描述】:

我有三个数据集说

df1 <- data.frame( x= rnorm(N), y = rnorm(N))
df2 <- data.frame( x= rnorm(N), y = rnorm(N))
df3 <- data.frame( x= rnorm(N), y = rnorm(N))

我想对变量x进行截断:如果是负数,则等于0。这是代码

map( list(df1,df2,df3), ~ifelse( .x$x <0, 0, .x$x))

但原来的df1, df2, df3没有修改。如何对原始数据帧进行这种修改?

【问题讨论】:

    标签: r dplyr tidyverse purrr


    【解决方案1】:

    在 R 中(至少在大多数情况下),你必须分配一个对象来修改它。

    虽然在 python 中您可以直接分配给元组 (df1,df2,df3),但不幸的是,在 R 中这是不可能的。

    因此,如果你真的想修改原始对象,你必须手动进行:

    df1 = ifelse(df1$x <0, 0, df1$x)
    df2 = ifelse(df2$x <0, 0, df2$x)
    df3 = ifelse(df3$x <0, 0, df3$x)
    

    但是,您可以使用列表实现非常相似的效果:

    library(purrr)
    set.seed(1)
    N=10
    df1 <- data.frame( x= rnorm(N), y = rnorm(N))
    df2 <- data.frame( x= rnorm(N), y = rnorm(N))
    df3 <- data.frame( x= rnorm(N), y = rnorm(N))
    
    x=list(df1=df1, df2=df2, df3=df3)
    y=map(x, ~ifelse( .x$x <0, 0, .x$x))
    y$df1
    #>  [1] 0.0000000 0.1836433 0.0000000 1.5952808 0.3295078 0.0000000 0.4874291
    #>  [8] 0.7383247 0.5757814 0.0000000
    

    reprex package (v1.0.0) 于 2021-03-14 创建

    请注意,命名列表元素很重要。

    编辑:

    根据您的评论,您的原始代码似乎不是您想要的。使用 ifelse() 将返回一个向量。如果要将此算法应用于多个列,则必须使用其他函数,例如dplyr::mutate()。您可以通过https://dplyr.tidyverse.org了解更多信息。

    这样就可以了:

    library(purrr)
    library(dplyr)
    set.seed(1)
    N=10
    df1 <- data.frame( x= rnorm(N), y = rnorm(N))
    df2 <- data.frame( x= rnorm(N), y = rnorm(N))
    df3 <- data.frame( x= rnorm(N), y = rnorm(N))
    
    clean_df = function(df){
        #use either everything() or just x, I'm not sure about what you really want
        df %>% mutate(across(everything(), ~ifelse( .x<0, 0, .x))) 
    }
    
    x=list(df1=df1, df2=df2, df3=df3)
    y=map(x, clean_df)
    y$df1
    #>            x         y
    #> 1  0.0000000 1.5117812
    #> 2  0.1836433 0.3898432
    #> 3  0.0000000 0.0000000
    #> 4  1.5952808 0.0000000
    #> 5  0.3295078 1.1249309
    #> 6  0.0000000 0.0000000
    #> 7  0.4874291 0.0000000
    #> 8  0.7383247 0.9438362
    #> 9  0.5757814 0.8212212
    #> 10 0.0000000 0.5939013
    

    reprex package (v1.0.0) 于 2021-03-15 创建

    【讨论】:

    • 谢谢!但是y只返回变量x,我希望它返回原始数据帧。
    【解决方案2】:

    您可以使用lst 代替list 创建命名列表,使用map 执行操作并使用list2env 更改原始数据帧。

    library(dplyr)
    library(purrr)
    
    res <- map(lst(df1,df2,df3), ~.x %>% mutate(x = ifelse(x < 0, 0, x)))
    #Using pmax would also give the same output
    #res <- map(lst(df1,df2,df3), ~.x %>% mutate(x = pmax(x, 0)))
    list2env(res, .GlobalEnv)
    

    【讨论】:

      猜你喜欢
      • 2019-09-13
      • 2017-05-09
      • 2012-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多