>source

아래 스크린 샷과 같이 2 개의 열이있는 데이터 세트가 있습니다. 개인 명, 회사 명

> dput(df)
structure(list(Name = c("ABC", "BCD", "CDE", "DEF", "EFG", "FGH", 
"GHI", "HIJ", "IJK", "JKL"), Company = c("A", "A", "A", "A", 
"B", "B", "C", "C", "C", "C")), class = "data.frame", row.names = c(NA, 
-10L))
> df
   Name Company
1   ABC       A
2   BCD       A
3   CDE       A
4   DEF       A
5   EFG       B
6   FGH       B
7   GHI       C
8   HIJ       C
9   IJK       C
10  JKL       C

데이터 세트를 2 개의 하위 집합으로 분할하려면 어떻게해야합니까? 각 하위 집합에는 같은 회사의 직원 수가 동일합니까?

예를 들어, 회사 A에는 총 4 명이 있습니다. 회사 A 그룹에는 두 개의 하위 집합이 있습니다. 즉, 회사 B, C의 경우와 비슷하게 하위 집합 1에 2 명, 하위 집합 2에 다른 2 명이 있습니다.

동일한 Campany에있는 홀수의 사람들의 경우 무작위로 하위 집합을 선택하여 동점을 끊을 수 있습니다.

감사!

  • 답변 # 1

    이 시도 tidyverse 얻기 위해 접근랜덤데이터를 두 개의 하위 집합으로 나눕니다.

    > df
       Name Company
    1   ABC       A
    2   BCD       A
    3   CDE       A
    4   DEF       A
    5   EFG       B
    6   FGH       B
    7   GHI       C
    8   HIJ       C
    9   IJK       C
    10  JKL       C
    
    

    접근 방식 -1두 개의 개별 데이터 프레임이있는 목록에 결과를 원하는 경우

    library(tidyverse)
    set.seed(123) # set the seed to replicate the result lateron
    df %>% mutate(id = row_number()) %>% group_by(Company) %>% mutate(n = n()) %>%
      sample_n(n*0.5) %>% mutate(d = 1) %>% ungroup() %>% select(id, d) %>% 
      right_join(df %>% mutate(id = row_number()), by = "id") %>%
      mutate(d = if_else(is.na(d), 2, d)) %>% group_split(d)
    
    <list_of<
      tbl_df<
        id     : integer
        d      : double
        Name   : character
        Company: character
      >
    >[2]>
    [[1]]
    # A tibble: 5 x 4
         id     d Name  Company
      <int> <dbl> <chr> <chr>  
    1     3     1 CDE   A      
    2     4     1 DEF   A      
    3     5     1 EFG   B      
    4     8     1 HIJ   C      
    5     9     1 IJK   C      
    [[2]]
    # A tibble: 5 x 4
         id     d Name  Company
      <int> <dbl> <chr> <chr>  
    1     1     2 ABC   A      
    2     2     2 BCD   A      
    3     6     2 FGH   B      
    4     7     2 GHI   C      
    5    10     2 JKL   C
    
    

    원하는 경우 두 개의 개별 csv 파일이 생성됩니다.

    set.seed(123)
    df %>% mutate(id = row_number()) %>% group_by(Company) %>% mutate(n = n()) %>%
      sample_n(n*0.5) %>% mutate(d = 1) %>% ungroup() %>% select(id, d) %>% 
      right_join(df %>% mutate(id = row_number()), by = "id") %>%
      mutate(d = if_else(is.na(d), 2, d)) %>% group_split(d) %>% map2(c("file1.csv", "file2.csv"), ~ write.csv(.x, .y))
    
    

    위의 코드는 getwd () 디렉토리에 2 개의 csv 파일을 작성합니다.

    접근 방식 -2또한 할 수 있습니다

    set.seed(123)
    df1 <- df %>% mutate(id = row_number()) %>% group_by(Company) %>% mutate(n = n()) %>%
      sample_n(n*0.5) %>% mutate(set_no = "Set1") %>% ungroup() %>% select(-n, -id)
    
    df2 <- df %>% mutate(id = row_number()) %>% filter(!id %in% df1$id) %>% 
      mutate(set_no = "Set2") %>% select(-id)
    
    

    결과 작성csv에서

    write.csv(df1, "subset1.csv")
    write.csv(df2, "subset2.csv")
    
    

    기둥 idd 도우미 열입니다. id 열은 그룹에 홀수 항목이있는 경우 행/레코드가 남지 않도록합니다. d 하위 그룹 번호를 식별하는 데 도움이됩니다.

    회사에 홀수 레코드가있는 경우 하위 집합의 행 수가 다르거 나 같지 않을 수 있습니다.

  • 답변 # 2

    다음을 사용하여 하위 집합 시퀀스의 모듈로 2를 계산할 수 있습니다. ave .

    r <- transform(d, sub=ave(company, company, FUN=function(x) paste0("sub", seq(x) %% 2 + 1)))
    r
    #       name company  sub
    # 1     alex       A sub2
    # 2    malan       A sub1
    # 3  matteis       A sub2
    # 4  fenwick       A sub1
    # 5  nicolas       B sub2
    # 6   cleary       B sub1
    # 7      fin       C sub2
    # 8    stijn       C sub1
    # 9  antoine       C sub2
    # 10     fin       C sub1
    # 11   stijn       C sub2
    # 12 antoine       C sub1
    
    

    검사:

    with(r, table(company, sub))
    # company sub1 sub2
    #       A    2    2
    #       B    1    1
    #       C    1    2
    
    

    실제로 회사가 예제와 같이 주문 된 경우 다음을 수행 할 수 있습니다.

    d$sub <- NA
    d$sub[] <- paste0("sub", 1:2)  ## throws a warning when `nrow` is uneven
    d
    #      name company  sub
    # 1    alex       A sub1
    # 2   malan       A sub2
    # 3 matteis       A sub1
    # 4 fenwick       A sub2
    # 5 nicolas       B sub1
    # 6  cleary       B sub2
    # 7     fin       C sub1
    # 8   stijn       C sub2
    # 9 antoine       C sub1
    
    

    <시간 />

    데이터:

    d <- structure(list(name = c("alex", "malan", "matteis", "fenwick", 
    "nicolas", "cleary", "fin", "stijn", "antoine"), company = c("A", 
    "A", "A", "A", "B", "B", "C", "C", "C")), class = "data.frame", row.names = c(NA, 
    -9L))
    
    

  • 답변 # 3

    당신이 사용할 수있는 avesample 처럼:

    set.seed(42)
    df$su <- ave(df$Company, df$Company, FUN=function(x)
     sample(rep(1:2, ceiling(length(x)/2)), length(x)))
    df
    #   Name Company su
    #1   ABC       A  1
    #2   BCD       A  2
    #3   CDE       A  1
    #4   DEF       A  2
    #5   EFG       B  2
    #6   FGH       B  1
    #7   GHI       C  2
    #8   HIJ       C  2
    #9   IJK       C  1
    #10  JKL       C  1
    
    

관련 자료

  • 이전 json - 값을 얻는 방법 (파이썬)
  • 다음 functional programming - 두 개의 술어에서 술어를 생성하십시오 (monoid에 대한 작업, 폴드?)