[r] R에서 동등한 Case 문

필드 중 하나에 일반적으로 7-8 개의 값이있는 데이터 프레임에 변수가 있습니다. 데이터 프레임 내의 새 변수 내에서 3 개 또는 4 개의 새 범주를 축소하고 싶습니다. 가장 좋은 방법은 무엇입니까?

SQL과 같은 도구를 사용했지만 R에서 이것을 공격하는 방법을 잘 모르겠다면 CASE 문을 사용합니다.

당신이 제공 할 수있는 어떤 도움이라도 대단히 감사 할 것입니다!



답변

case_when()2016 년 5 월에 dplyr에 추가 된은 memisc::cases().

예를 들면 :

library(dplyr)
mtcars %>%
  mutate(category = case_when(
    .$cyl == 4 & .$disp < median(.$disp) ~ "4 cylinders, small displacement",
    .$cyl == 8 & .$disp > median(.$disp) ~ "8 cylinders, large displacement",
    TRUE ~ "other"
  )
)

dplyr 0.7.0부터,

mtcars %>%
  mutate(category = case_when(
    cyl == 4 & disp < median(disp) ~ "4 cylinders, small displacement",
    cyl == 8 & disp > median(disp) ~ "8 cylinders, large displacement",
    TRUE ~ "other"
  )
)


답변

패키지 의 cases기능을 살펴보십시오 memisc. 사용하는 두 가지 방법으로 케이스 기능을 구현합니다. 패키지의 예에서 :

z1=cases(
    "Condition 1"=x<0,
    "Condition 2"=y<0,# only applies if x >= 0
    "Condition 3"=TRUE
    )

여기서, x그리고 y두 개의 벡터이다.

참조 : memisc 패키지 , 사례 예


답변

그렇다면 factor표준 방법으로 수준을 변경할 수 있습니다.

df <- data.frame(name = c('cow','pig','eagle','pigeon'),
             stringsAsFactors = FALSE)
df$type <- factor(df$name) # First step: copy vector and make it factor
# Change levels:
levels(df$type) <- list(
    animal = c("cow", "pig"),
    bird = c("eagle", "pigeon")
)
df
#     name   type
# 1    cow animal
# 2    pig animal
# 3  eagle   bird
# 4 pigeon   bird

간단한 함수를 래퍼로 작성할 수 있습니다.

changelevels <- function(f, ...) {
    f <- as.factor(f)
    levels(f) <- list(...)
    f
}

df <- data.frame(name = c('cow','pig','eagle','pigeon'),
                 stringsAsFactors = TRUE)

df$type <- changelevels(df$name, animal=c("cow", "pig"), bird=c("eagle", "pigeon"))


답변

switch문을 사용하는 방법은 다음과 같습니다 .

df <- data.frame(name = c('cow','pig','eagle','pigeon'),
                 stringsAsFactors = FALSE)
df$type <- sapply(df$name, switch,
                  cow = 'animal',
                  pig = 'animal',
                  eagle = 'bird',
                  pigeon = 'bird')

> df
    name   type
1    cow animal
2    pig animal
3  eagle   bird
4 pigeon   bird

이것의 한 가지 단점은 animal각 항목에 대해 카테고리 이름 ( 등) 을 계속 작성해야한다는 것 입니다. 아래와 같이 범주를 정의 할 수있는 것이 구문 적으로 더 편리합니다 ( R의 데이터 프레임에 열을 추가하는 방법 과 매우 유사한 질문 참조 )

myMap <- list(animal = c('cow', 'pig'), bird = c('eagle', 'pigeon'))

어떻게 든이 매핑을 “반전”하고 싶습니다. 내 자신의 invMap 함수를 작성합니다.

invMap <- function(map) {
  items <- as.character( unlist(map) )
  nams <- unlist(Map(rep, names(map), sapply(map, length)))
  names(nams) <- items
  nams
}

그런 다음 위의지도를 다음과 같이 반전합니다.

> invMap(myMap)
     cow      pig    eagle   pigeon
"animal" "animal"   "bird"   "bird"

그리고 이것을 사용 type하여 데이터 프레임에 열 을 추가하는 것은 쉽습니다 .

df <- transform(df, type = invMap(myMap)[name])

> df
    name   type
1    cow animal
2    pig animal
3  eagle   bird
4 pigeon   bird


답변

‘스위치’에 대한 제안이 보이지 않습니다. 코드 예제 (실행) :

x <- "three"
y <- 0
switch(x,
       one = {y <- 5},
       two = {y <- 12},
       three = {y <- 432})
y


답변

Imho, 가장 간단하고 보편적 인 코드 :

dft=data.frame(x = sample(letters[1:8], 20, replace=TRUE))
dft=within(dft,{
    y=NA
    y[x %in% c('a','b','c')]='abc'
    y[x %in% c('d','e','f')]='def'
    y[x %in% 'g']='g'
    y[x %in% 'h']='h'
})


답변

거기에있다 switch문하지만 나는 내가 그것을해야한다 생각하는 방식으로 작동 얻을 수가 없다. 예제를 제공하지 않았으므로 요인 변수를 사용하여 하나를 만들 것입니다.

 dft <-data.frame(x = sample(letters[1:8], 20, replace=TRUE))
 levels(dft$x)
[1] "a" "b" "c" "d" "e" "f" "g" "h"

재 할당에 적합한 순서로 원하는 범주를 지정하는 경우 요인 또는 숫자 변수를 인덱스로 사용할 수 있습니다.

c("abc", "abc", "abc", "def", "def", "def", "g", "h")[dft$x]
 [1] "def" "h"   "g"   "def" "def" "abc" "h"   "h"   "def" "abc" "abc" "abc" "h"   "h"   "abc"
[16] "def" "abc" "abc" "def" "def"

dft$y <- c("abc", "abc", "abc", "def", "def", "def", "g", "h")[dft$x] str(dft)
'data.frame':   20 obs. of  2 variables:
 $ x: Factor w/ 8 levels "a","b","c","d",..: 4 8 7 4 6 1 8 8 5 2 ...
 $ y: chr  "def" "h" "g" "def" ...

나중에 두 가지 다른 스위치 기능이 있다는 것을 알게되었습니다. 일반적인 기능은 아니지만 switch.numeric또는 로 생각해야합니다 switch.character. 첫 번째 인수가 R ‘인자’인 switch.numeric경우 대부분의 사람들은 요인이 문자로 표시되고 모든 함수가이를 처리 할 것이라는 잘못된 가정을하기 때문에 문제를 일으킬 가능성 이있는 행동이 발생합니다.