Использование dplyr для создания нового столбца - PullRequest
4 голосов
/ 28 мая 2020

Привет, у меня есть df, например

Groups COL1 COL2
G1 1 A
G1 1 C
G1 2 A
G1 2 B
G1 5 C
G1 6 C
G2 7 B
G2 7 B
G2 8 C
G3 10 C
G3 10 A
G3 11 B
G4 12 C
G4 12 C

, и идея состоит в том, чтобы добавить новый столбец COL3 и

group_by(Groups, COL1) %>%
  mutate(COL3 = COL1(A>B>C))

, идея заключается в том, что внутри групп и COL1 , если два значения COL2 различны, если A присутствует с A или C, все значения становятся A, если A отсутствует, но B есть здесь, все значения становятся B, и если есть только C, все значения становятся C (они уже есть).

так что A> B и B> C вот ожидаемый результат:

Groups COL1 COL2 COL3
G1 1 A A
G1 1 C A 
G1 2 A A
G1 2 B A
G1 5 C C
G1 6 C C
G2 7 B B
G2 7 B B
G2 8 C C
G3 10 C A
G3 10 A A
G3 11 B B
G4 12 C C
G4 12 C C

Есть у кого-нибудь идея?

Ответы [ 4 ]

6 голосов
/ 28 мая 2020

Если COL2 можно осмысленно отсортировать, min() должно работать:

df <- structure(
    list(Groups = c("G1", "G1", "G1", "G1", "G1", "G1", "G2", "G2", "G2", "G3",
                    "G3", "G3", "G4", "G4"),
         COL1 = c(1L, 1L, 2L, 2L, 5L, 6L, 7L, 7L, 8L, 10L, 10L, 11L, 12L, 12L),
         COL2 = c("A", "C", "A", "B", "C", "C", "B", "B", "C", "C", "A", "B",
                  "C", "C")),
    class = "data.frame", row.names = c(NA, -14L))

library("dplyr")


df %>% 
    group_by(Groups, COL1) %>% 
    mutate(COL3 = min(COL2))
#> # A tibble: 14 x 4
#> # Groups:   Groups, COL1 [9]
#>    Groups  COL1 COL2  COL3 
#>    <chr>  <int> <chr> <chr>
#>  1 G1         1 A     A    
#>  2 G1         1 C     A    
#>  3 G1         2 A     A    
#>  4 G1         2 B     A    
#>  5 G1         5 C     C    
#>  6 G1         6 C     C    
#>  7 G2         7 B     B    
#>  8 G2         7 B     B    
#>  9 G2         8 C     C    
#> 10 G3        10 C     A    
#> 11 G3        10 A     A    
#> 12 G3        11 B     B    
#> 13 G4        12 C     C    
#> 14 G4        12 C     C

Создано 28 мая 2020 г. пакетом реплекс (v0. 3,0)

6 голосов
/ 28 мая 2020

Думаю, это дает ожидаемый результат:

df %>% 
  group_by(Groups, COL1) %>% 
  mutate(COL2 = levels(COL2)[min(as.numeric(COL2))])
#> # Groups:   Groups, COL1 [9]
#>    Groups  COL1 COL2 
#>    <fct>  <int> <chr>
#>  1 G1         1 A    
#>  2 G1         1 A    
#>  3 G1         2 A    
#>  4 G1         2 A    
#>  5 G1         5 C    
#>  6 G1         6 C    
#>  7 G2         7 B    
#>  8 G2         7 B    
#>  9 G2         8 C    
#> 10 G3        10 A    
#> 11 G3        10 A    
#> 12 G3        11 B    
#> 13 G4        12 C    
#> 14 G4        12 C 

3 голосов
/ 28 мая 2020

Альтернативное решение с использованием case_when, если вам нужно сопоставление вручную:

df %>% 
  group_by(Groups, COL1) %>%
  mutate(COL3 = case_when(any(COL2 == "A") ~ "A", 
                          any(COL2 == "B") ~ "B", 
                          any(COL2 == "C") ~ "C", 
                          TRUE ~ "no_match"))
#   A tibble: 14 x 4
#   Groups:   Groups, COL1 [9]
#    Groups  COL1 COL2  COL3 
#    <chr>  <dbl> <chr> <chr>
#  1 G1         1 A     A    
#  2 G1         1 C     A    
#  3 G1         2 A     A    
#  4 G1         2 B     A    
#  5 G1         5 C     C    
#  6 G1         6 C     C    
#  7 G2         7 B     B    
#  8 G2         7 B     B    
#  9 G2         8 C     C    
# 10 G3        10 C     A    
# 11 G3        10 A     A    
# 12 G3        11 B     B    
# 13 G4        12 C     C    
# 14 G4        12 C     C 
1 голос
/ 28 мая 2020

Вариант с ave

df1$COL3 <- with(df1, ave(COL1, Groups, FUN = min))
...