[r] dplyr 조건부 값으로 변경

4 개의 열이있는 큰 데이터 프레임 ( “myfile”)에서 처음 4 개의 열을 기준으로 조건부 값이있는 다섯 번째 열을 추가해야합니다.

주로 큰 데이터 세트의 속도 때문에 dplyr및로 답변을 선호합니다 mutate.

내 데이터 프레임은 다음과 같습니다.

  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?



답변

이 시도:

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

노트

데이터 프레임에 대해 더 나은 이름을 얻을 것을 제안하십시오. myfile은 마치 파일 이름을 가지고있는 것처럼 보이게합니다.

위에서 사용 된 입력 :

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"))

업데이트 1 원래 게시 dplyr 이후는 변경 %.%%>%따라 이렇게 수정 한 대답.

업데이트 2 dplyr은 이제 case_when다른 솔루션을 제공합니다.

myfile %>%
       mutate(V5 = case_when(V1 == 1 & V2 != 4 ~ 1,
                             V2 == 4 & V3 != 1 ~ 2,
                             TRUE ~ 0))


답변

와 함께 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")
x$V5 = case_when(x$V1==1 & x$V2!=4 ~ 1,
                 x$V2==4 & x$V3!=1 ~ 2,
                 TRUE ~ 0)

로 표현 dplyr::mutate하면 다음을 제공합니다.

x = x %>% mutate(
     V5 = case_when(
         V1==1 & V2!=4 ~ 1,
         V2==4 & V3!=1 ~ 2,
         TRUE ~ 0
     )
)

주의 사항 NA은 오해의 소지가 될 수있는, 특별하게 취급되지 않습니다. NA조건이 일치하지 않는 경우에만 함수가 반환 됩니다. TRUE ~ ...내 예제에서했던 것처럼을 사용 하여 줄을 넣으면 반환 값은 절대 NA.

따라서 다음 과 같은 문장을 추가하여 그것이 속한 위치 를 명시 적으로 말해야 case_when합니다 . 힌트 :이 기능은 때때로 여기에서 정말 유용 할 수 있습니다!NAis.na(x$V1) | is.na(x$V3) ~ NA_integer_dplyr::coalesce()

또한 NA일반적으로 단독으로 작동하지 않으므로 특수 NA값 을 입력해야 합니다 : NA_integer_, NA_character_또는 NA_real_.


답변

그것은처럼 보이는 derivedFactor으로부터 mosaic패키지가이 설계되었습니다. 이 예에서는 다음과 같습니다.

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"이 접근 방식에 대한 도움말 파일에 설명되어 있습니다 – 설정은 “다른”조건 derivedFactor.


답변