结合mutate和条件值

在一个包含四列的大数据框(“myfile”)中,我必须根据前四列添加一个包含值的第五列。 最近我已经成为dplyr的粉丝,主要是因为它在大型数据集中的速度。 所以我想知道如果我可以使用mutate函数来处理我的问题。

我的dataframe(实际上是一个更短的版本)看起来有点像这样:

V1 V2 V3 V4 1 1 2 3 5 2 2 4 4 1 3 1 4 1 1 4 4 5 1 3 5 5 5 5 4 

第五列(V5)的值基于一些有条件的规则:

 if (V1==1 & V2!=4){ V5 <- 1 } else if (V2==4 & V3!=1){ V5 <- 2 } else { V5 <- 0 } 

现在我想使用mutate函数在所有行上使用这些规则(所以我不必使用慢循环)。 像这样的东西(是的,我知道这是行不通的):

 myfile <- mutate(myfile, if (V1==1 & V2!=4){V5 = 1} else if (V2==4 & V3!=1){V5 = 2} else {V5 = 0}) 

这应该是结果:

  V1 V2 V3 V4 V5 1 1 2 3 5 1 2 2 4 4 1 2 3 1 4 1 1 0 4 4 5 1 3 0 5 5 5 5 4 0 

如何在dplyr做到这dplyr

尝试这个:

 > myfile %>% mutate(V5 = (V1 == 1 & V2 != 4) + 2 * (V2 == 4 & V3 != 1)) V1 V2 V3 V4 V5 1 1 2 3 5 1 2 2 4 4 1 2 3 1 4 1 1 0 4 4 5 1 3 0 5 5 5 5 4 0 

或这个:

 > myfile %>% mutate(V5 = ifelse(V1 == 1 & V2 != 4, 1, ifelse(V2 == 4 & V3 != 1, 2, 0))) V1 V2 V3 V4 V5 1 1 2 3 5 1 2 2 4 4 1 2 3 1 4 1 1 0 4 4 5 1 3 0 5 5 5 5 4 0 

build议你为你的数据框取一个更好的名字。 myfile使它看起来好像它拥有一个文件名。

上面使用了这个input:

 myfile <- structure(list(V1 = c(1L, 2L, 1L, 4L, 5L), V2 = c(2L, 4L, 4L, 5L, 5L), V3 = c(3L, 4L, 1L, 1L, 5L), V4 = c(5L, 1L, 1L, 3L, 4L )), .Names = c("V1", "V2", "V3", "V4"), class = "data.frame", row.names = c("1", "2", "3", "4", "5")) 

更新自从最初发布dplyr已经将%.%更改为%>%所以相应地修改了答案。

它看起来像mosaic包中的derivedFactor是为此devise的。 在这个例子中,它看起来像这样:

 library(mosaic) myfile <- mutate(myfile, V5 = derivedFactor( "1" = (V1==1 & V2!=4), "2" = (V2==4 & V3!=1), .method = "first", .default = 0 )) 

(如果您希望结果是数字而不是因子,请使用derivedFactor包装as.numeric 。)

请注意, .default选项与.method = "first"设置“else”条件 – 此方法在derivedFactor的帮助文件中进行了derivedFactor

dplyr 0.7.2 ,你可以使用非常有用的case_when函数:

 x=read.table(text="V1 V2 V3 V4 1 1 2 3 5 2 2 4 4 1 3 1 4 1 1 4 4 5 1 3 5 5 5 5 4", col.names=c("V1", "V2", "V3", "V4")) x$V5 = case_when(m$V1==1 & x$V2!=4 ~ 1, x$V2==4 & x$V3!=1 ~ 2, TRUE ~ 0) 

请注意, NA没有被特别对待,因为它可能会引起误解。 在条件不匹配的情况下,函数将返回NA (所以如果有TRUE ~ ... ,则表示从不)。 你必须通过添加一个像is.na(x$V1) | is.na(x$V3) ~ NA_integer_这样的语句来is.na(x$V1) | is.na(x$V3) ~ NA_integer_告诉它将NA放在它所属的位置 is.na(x$V1) | is.na(x$V3) ~ NA_integer_