【问题标题】:For loop using mutate comparing two data frames使用 mutate 比较两个数据帧的 For 循环
【发布时间】:2021-10-10 14:34:51
【问题描述】:

我有两个具有相同变量名称的数据框,第一个带有值,第二个带有影子变量。我想根据 df2 中的值对 df1 上的变量进行变异(如果 df2$x > 90,那么我想将 df1$x 变异为 NA)。

# Example input dataframes
df1 <- data.frame(
    x = c(123, 456, 789),
    y = c(120, 745, 789),
    z = c(852, 741, 963)
)

df2 <- data.frame(
    x = c(1, 95, 96),
    y = c(1, 99, 1),
    z = c(98, 1, 1)
)

我想要获得的是一个如下所示的数据框:

#        x       y      z 
#1      123     120      NA         
#2      NA      NA      741         
#3      NA      789     963

我得到了我想要的结果:

result <- df1%>%
  mutate(x= replace(x, df2$x > 90 , NA  )) %>%
  mutate(y= replace(y, df2$y > 90 , NA )) %>%
  mutate(z= replace(z, df2$z > 90 , NA ))

但我想改用 for 循环,因为我有几个变量。我试过了:

for (i in c("x" , "y" , "z") {
 result <- df1%>%
  mutate(i= replace(i, df2$i > 90 , NA  )) 
}

但是没有用...所以我在这里寻求您的指导。提前谢谢!

【问题讨论】:

    标签: r for-loop dplyr


    【解决方案1】:

    1) 跨 这适用于处理所有列:

    library(dplyr)
    df1 %>%
      mutate(across(.fn = ~ replace(., df2[[cur_column()]] > 90, NA)))
    ##     x   y   z
    ## 1 123 120  NA
    ## 2  NA  NA 741
    ## 3  NA 789 963
    

    循环

    2) 循环与cross 关于问题中的循环,可以使用 mutate(across(...)) 。我们首先制作 df1 的副本以保留输入。结果在 df1_na 中。

    library(dplyr)
    df1_na <- df1
    for(nm in names(df1)) {
      df1_na <- df1_na %>% mutate(across(all_of(nm), ~ replace(., df2[[nm]] > 90, NA)))
    }
    

    3) rlang 或使用 rlang:

    library(dplyr)
    df1_na <- df1
    for(nm in names(df1)) {
      df1_na <- df1_na %>% mutate({{nm}} := replace(.[[nm]], df2[[nm]] > 90, NA))
    }
    

    4) 基数或只有基数的循环(尽管另一个答案中提供了更简单的基数解决方案)。

    df1_na <- df1
    for(nm in names(df1)) df1_na[[nm]] <- replace(df1_na[[nm]], df2[[nm]] > 90, NA)
    

    【讨论】:

    • 谢谢!!我尝试使用选项 2,但 df2 中的一些零也在 df1 中转换为 NA。我刚刚添加了第二行 mutate 将 > 90 更改为 ==0 就完成了。
    • df2 中的零不会导致 NA 出现在 df1 中,因此必须有一些未显示的内容。如果您可以编辑问题以提供发生这种情况的第二个测试用例,我们可以尝试解决它。​​
    • 我的错!我使用了错误的 df,现在它可以在没有额外的行的情况下工作了哈哈再次感谢
    【解决方案2】:

    我们可以使用replace

    replace(df1, df2 > 90, NA)
    

    【讨论】:

      【解决方案3】:

      如果两个数据框的维度相同,您可以这样做 -

      df1[df2 > 90] <- NA
      df1
      
      #    x   y   z
      #1 123 120  NA
      #2  NA  NA 741
      #3  NA 789 963
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多