使用dplyr有条件地更新多个变量

使用dplyr有条件地更新多个变量,r,dplyr,R,Dplyr,我试图使用一个条件语句来使用dplyr更新R中的多个变量。我有一些工作代码张贴在下面,但我觉得它是非常低效的,并相信一定有一个更好的方式做它 编辑:对程序目的的文字描述。我们的想法是利用iris数据集,根据物种值更新多个变量,例如,如果物种==setosa,那么物种=setosa,萼片长度*=1.5,萼片宽度*=0.5 library(dplyr) library(tibble) multi_update <- function(species , sepal.length , sepa

我试图使用一个条件语句来使用dplyr更新R中的多个变量。我有一些工作代码张贴在下面,但我觉得它是非常低效的,并相信一定有一个更好的方式做它

编辑:对程序目的的文字描述。我们的想法是利用iris数据集,根据物种值更新多个变量,例如,如果物种==setosa,那么物种=setosa,萼片长度*=1.5,萼片宽度*=0.5

library(dplyr)
library(tibble)

multi_update <- function(species , sepal.length , sepal.width , ret){

  if ( species == "setosa")  {
    RET <- list( 
      Species      = "SETOSA",
      Sepal.Length = sepal.length * 1.5,
      Sepal.Width  = sepal.width * 0.5
    )
  } else if ( species == "versicolor") {
    RET <- list( 
      Species      = "VERSI",
      Sepal.Length = sepal.length * 2,
      Sepal.Width  = sepal.width * 1.5
    )
  } else {
    RET <- list( 
      Species      = species,
      Sepal.Length = sepal.length ,
      Sepal.Width  = sepal.width 
    )
  }                     
  return( RET[[ret]] )
}

iris %>% 
  tbl_df %>% 
  mutate( Sepal.Length = mapply(multi_update , Species , Sepal.Length , Sepal.Width , "Sepal.Length")) %>% 
  mutate( Sepal.Width  = mapply(multi_update , Species , Sepal.Length , Sepal.Width , "Sepal.Width")) %>% 
  mutate( Species      = mapply(multi_update , Species , Sepal.Length , Sepal.Width , "Species"))

我们可以创建一个key-val数据集,与原始数据集连接,并对列进行变异

library(dplyr)
kval <- data.frame(Species = c("setosa", "versicolor", "virginica"),
       Species.x = c("SETOSA", "VERSI", "virginica"), 
      Sepal.Length = c(1.5, 2, 1), Sepal.Width = c(0.5, 1.5, 1))
res <- left_join(iris, kval, by = "Species") %>% 
           mutate(Species = Species.x, Sepal.Length = Sepal.Length.x*Sepal.Length.y, 
             Sepal.Width = Sepal.Width.x * Sepal.Width.y) %>%
            select(-matches("(.x|.y)$"))
head(res)
#  Petal.Length Petal.Width Species Sepal.Length Sepal.Width
#1          1.4         0.2  SETOSA         7.65        1.75
#2          1.4         0.2  SETOSA         7.35        1.50
#3          1.3         0.2  SETOSA         7.05        1.60
#4          1.5         0.2  SETOSA         6.90        1.55
#5          1.4         0.2  SETOSA         7.50        1.80
#6          1.7         0.4  SETOSA         8.10        1.95

我们可以创建一个key-val数据集,与原始数据集连接,并对列进行变异

library(dplyr)
kval <- data.frame(Species = c("setosa", "versicolor", "virginica"),
       Species.x = c("SETOSA", "VERSI", "virginica"), 
      Sepal.Length = c(1.5, 2, 1), Sepal.Width = c(0.5, 1.5, 1))
res <- left_join(iris, kval, by = "Species") %>% 
           mutate(Species = Species.x, Sepal.Length = Sepal.Length.x*Sepal.Length.y, 
             Sepal.Width = Sepal.Width.x * Sepal.Width.y) %>%
            select(-matches("(.x|.y)$"))
head(res)
#  Petal.Length Petal.Width Species Sepal.Length Sepal.Width
#1          1.4         0.2  SETOSA         7.65        1.75
#2          1.4         0.2  SETOSA         7.35        1.50
#3          1.3         0.2  SETOSA         7.05        1.60
#4          1.5         0.2  SETOSA         6.90        1.55
#5          1.4         0.2  SETOSA         7.50        1.80
#6          1.7         0.4  SETOSA         8.10        1.95

我认为最好创建一个键/变量数据集,然后加入原始数据集。请用文字说明您的函数应该做什么,这样其他人就不必猜测它的目的IRIS%>%mutatesp=if_elspecies%in%csetosa,versicolor,Species,NA_integer,萼片长度=如果其他种类==刚毛,萼片长度*1.5,萼片长度*2,Sepl.Length更新为包含@DocendDiscimus要求的文字描述我认为最好创建一个键/变量数据集,然后与原始数据集连接。请用文字说明函数应该做什么,这样其他人就不必猜测它的用途Iris%>%mutatesp=如果其他种类%在%csetosa中,花色,种,NA_integer,萼片长度=如果其他种==刚毛,萼片长度*1.5,萼片长度*2,萼片长度更新为包含@DocendDiscimust要求的文字描述。这很好,对于更复杂的衍生,例如如果刚毛,那么萼片长度=萼片长度*1.5如果维吉尼亚,那么萼片长度=12如果。。。。然后萼片长度=萼片长度-2@C_G您可以根据您拥有的任何新值更新keyval数据集kval,因此,在新的情况下,将“物种”更改为与Sepal.Length中的值对应的值。这种方法的优点是,你可以有100个键/值对,并进行单连接,而不是许多嵌套的ifelseThanks作为解释,对不起,如果我很模糊,但我不太明白你会修改各种运算符的示例,你的示例似乎固定在乘法上,如果我想对一些进行乘法,对另一些进行加法或减法,该怎么办?@C_G无论你想要什么,你都可以在key val数据集中添加额外的列,然后通过普通物种进行连接,因此,在同一行上相乘或添加不同的列会更容易。@例如,如果您想要Petal.Length以及mutateSpecies=Species.x,NewLength=Sepal.Length.x*Sepal.Length.y+Petal.Length这很有效,对于更复杂的衍生,例如如果刚毛,那么萼片长度=萼片长度*1.5如果维吉尼亚,那么萼片长度=12如果。。。。然后萼片长度=萼片长度-2@C_G您可以根据您拥有的任何新值更新keyval数据集kval,因此,在新的情况下,将“物种”更改为与Sepal.Length中的值对应的值。这种方法的优点是,你可以有100个键/值对,并进行单连接,而不是许多嵌套的ifelseThanks作为解释,对不起,如果我很模糊,但我不太明白你会修改各种运算符的示例,你的示例似乎固定在乘法上,如果我想对一些进行乘法,对另一些进行加法或减法,该怎么办?@C_G无论你想要什么,你都可以在key val数据集中添加额外的列,然后通过普通物种进行连接,因此,在同一行上相乘或添加不同的列会更容易。@例如,如果您想要Petal.Length以及mutateSpecies=Species.x,NewLength=Sepal.Length.x*Sepal.Length.y+Petal.Length,则C_G