Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 类似于SQL的条件更新_R_Dplyr_Data.table - Fatal编程技术网

R 类似于SQL的条件更新

R 类似于SQL的条件更新,r,dplyr,data.table,R,Dplyr,Data.table,我有以下数据帧 library(tidyverse) x <- c(1,2,3,NA,NA,4,5) y <- c(1,2,3,5,5,4,5) z <- c(1,1,1,6,7,7,8) df <- data.frame(x,y,z) df x y z 1 1 1 1 2 2 2 1 3 3 3 1 4 NA 5 6 5 NA 5 7 6 4 4 7 7 5 5 8 但是,我必须为x和y变异函数添加if_else语句。这有可能使我的代码变得复杂和难以

我有以下数据帧

library(tidyverse)
x <- c(1,2,3,NA,NA,4,5)
y <- c(1,2,3,5,5,4,5)
z <- c(1,1,1,6,7,7,8)
df <- data.frame(x,y,z)

df
   x y z
1  1 1 1
2  2 2 1
3  3 3 1
4 NA 5 6
5 NA 5 7
6  4 4 7
7  5 5 8
但是,我必须为x和y变异函数添加if_else语句。这有可能使我的代码变得复杂和难以阅读。要给你一个SQL类比,考虑下面的代码

UPDATE df
SET x= 1, y= 2
WHERE z = 1;
我希望实现以下目标:

  • 提前指定更新条件,这样我就不必为每个mutate函数重复它
  • 我希望避免使用data.table或base R。我使用的是dplyr,因此我希望坚持使用它以保持一致性

    • 这里有一个带有
      map2
      的选项。循环遍历数据集的“x”、“y”列以及要更改的值,如果为真,则基于“z”的值应用
      case_
      ,然后返回新值,或者返回相同的列并
      bind
      将列与原始数据集绑定

      library(dplyr)
      library(purrr)
      map2_df(df %>%
                select(x, y), c(1, 2), ~ case_when(df$z == 1 ~ .y, TRUE ~ .x)) %>%
           bind_cols(df %>%
                       select(z), .) %>%
           select(names(df))
      

      或者使用
      base R
      ,创建一个逻辑向量,使用该向量对列“x”、“y”的行进行子集,并通过指定值的
      列表进行更新

      i1 <- df$z == 1
      df[i1, c('x', 'y')] <- list(1, 2)
      df
      #   x y z
      #1  1 2 1
      #2  1 2 1
      #3  1 2 1
      #4 NA 5 6
      #5 NA 5 7
      #6  4 4 7
      #7  5 5 8
      
      i1
      在R底

      transform(df,
                x = replace(x, z == 1, 1),
                y = replace(y, z == 1, 2))
      
      如果将条件存储在变量中,则无需多次键入

      condn = (df$z == 1)
      transform(df,
                x = replace(x, condn, 1),
                y = replace(y, condn, 2))
      

      如果您有SQL背景,您应该真正了解:

      库(data.table)
      
      dt使用发布在上的
      mutate_cond
      我们可以做到这一点:

      df %>% mutate_cond(z == 1, x = 1, y = 2)
      
      给予:

         x y z
      1  1 2 1
      2  1 2 1
      3  1 2 1
      4 NA 5 6
      5 NA 5 7
      6  4 4 7
      7  5 5 8
      
      sqldf 当然,您可以使用sqldf直接在SQL中实现它——忽略后端RSQLite发出的警告消息

      library(sqldf)
      sqldf(c("update df set x = 1, y = 2 where z = 1", "select * from df"))
      
      基尔 它在R底笔直向前:

      df[df$z == 1, c("x", "y")] <- list(1, 2)
      

      df[df$z==1,c(“x”,“y”)]谢谢你介绍我变异条件。我真的希望它包含在dplyr中!!
      
      df %>% mutate_cond(z == 1, x = 1, y = 2)
      
         x y z
      1  1 2 1
      2  1 2 1
      3  1 2 1
      4 NA 5 6
      5 NA 5 7
      6  4 4 7
      7  5 5 8
      
      library(sqldf)
      sqldf(c("update df set x = 1, y = 2 where z = 1", "select * from df"))
      
      df[df$z == 1, c("x", "y")] <- list(1, 2)