【问题标题】:Need help replacing character strings found in a column with a value in R需要帮助用 R 中的值替换列中找到的字符串
【发布时间】:2021-04-05 21:55:00
【问题描述】:

我对 R 中的数据争论仍然很陌生,所以请耐心等待。我有一个带有“品牌”列的数据框,有超过 1400 行和大约 200 个独特品牌。我将品牌分为 3 个不同的类别,并暂时将它们放在一个列表中(类似于下面的示例,但每个列表都有更多品牌)。

我正在尝试用整数替换品牌列中的品牌,但我希望每个列表中的品牌都具有相同的整数。如有必要,我可以重新组织品牌的结构。我的问题来自于让 R 识别列表中的各个品牌。我一直在玩 ifelse() 函数,但不能完全让 %in% 做我想做的事。谢谢!

A <- list("Brand A", "Brand B", "Brand C")
M <- list("Brand M", "Brand N", "Brand O")
Z <- list("Brand X", "Brand Y", "Brand Z")

【问题讨论】:

标签: r


【解决方案1】:

这是一种方法:

library(tidyverse)

df <- tibble(ID = 1:200,
                 brand = sample(c("Brand A", "Brand B", "Brand C",
                                  "Brand M", "Brand N", "Brand O",
                                  "Brand X", "Brand Y", "Brand Z"),
                                size = 200, replace = TRUE))
df
# A tibble: 200 x 2
#      ID brand  
#   <int> <chr>  
# 1     1 Brand X
# 2     2 Brand M
# 3     3 Brand A
# 4     4 Brand N
# 5     5 Brand M
# 6     6 Brand B
# 7     7 Brand X
# 8     8 Brand B
# 9     9 Brand N
# 10    10 Brand O
# … with 190 more rows


df_grouped <- df %>% 
  mutate(brand_group = case_when(brand %in% c("Brand A", "Brand B", "Brand C") ~ "A",
                                 brand %in% c("Brand M", "Brand N", "Brand O") ~ "M",
                                 brand %in% c("Brand X", "Brand Y", "Brand Z") ~ "Z"))

df_grouped
# A tibble: 200 x 3
#      ID brand   brand_group
#   <int> <chr>   <chr>      
# 1     1 Brand X Z          
# 2     2 Brand M M          
# 3     3 Brand A A          
# 4     4 Brand N M          
# 5     5 Brand M M          
# 6     6 Brand B A          
# 7     7 Brand X Z          
# 8     8 Brand B A          
# 9     9 Brand N M          
# 10    10 Brand O M          
# … with 190 more rows


df_int <- df_grouped %>% 
  mutate(brand_int = ifelse(brand_group == "A", 1, ifelse(brand_group == "M", 2, 3)))

df_int
# A tibble: 200 x 4
#      ID brand   brand_group brand_int
#   <int> <chr>   <chr>           <dbl>
# 1     1 Brand X Z                   3
# 2     2 Brand M M                   2
# 3     3 Brand A A                   1
# 4     4 Brand N M                   2
# 5     5 Brand M M                   2
# 6     6 Brand B A                   1
# 7     7 Brand X Z                   3
# 8     8 Brand B A                   1
# 9     9 Brand N M                   2
# 10    10 Brand O M                   2
# … with 190 more rows

编辑

您也可以使用case_when()一步将原品牌更改为整数,例如

df_int <- df %>% 
  mutate(brand_int = case_when(brand %in% c("Brand A", "Brand B", "Brand C") ~ 1,
                                 brand %in% c("Brand M", "Brand N", "Brand O") ~ 2,
                                 brand %in% c("Brand X", "Brand Y", "Brand Z") ~ 3))

df_int
# A tibble: 200 x 3
#      ID brand   brand_int
#   <int> <chr>       <dbl>
# 1     1 Brand X         3
# 2     2 Brand M         2
# 3     3 Brand A         1
# 4     4 Brand N         2
# 5     5 Brand M         2
# 6     6 Brand B         1
# 7     7 Brand X         3
# 8     8 Brand B         1
# 9     9 Brand N         2
# 10    10 Brand O         2
# … with 190 more rows

或者,如果要将品牌替换为同一列中的整数,可以使用transmute() 例如

df_int <- df %>% 
  transmute(brand_int = case_when(brand %in% c("Brand A", "Brand B", "Brand C") ~ 1,
                                 brand %in% c("Brand M", "Brand N", "Brand O") ~ 2,
                                 brand %in% c("Brand X", "Brand Y", "Brand Z") ~ 3))

df_int
# A tibble: 200 x 1
#   brand_int
#       <dbl>
# 1         3
# 2         2
# 3         1
# 4         2
# 5         2
# 6         1
# 7         3
# 8         1
# 9         2
# 10         2
# … with 190 more rows

【讨论】:

    【解决方案2】:

    您可以尝试merge + stack 如下所示

    merge(df,
      stack(list(A = A, M = M, Z = Z)),
      by.x = "brand",
      by.y = "values",
      all.x = TRUE
    )
    

    给了

         brand ID ind
    1  Brand A  8   A
    2  Brand A 10   A
    3  Brand A 12   A
    4  Brand B  2   A
    5  Brand B  9   A
    6  Brand C 13   A
    7  Brand C 19   A
    8  Brand M 17   M
    9  Brand M 18   M
    10 Brand M 15   M
    11 Brand N 11   M
    12 Brand N 16   M
    13 Brand O  6   M
    14 Brand O  7   M
    15 Brand O  5   M
    16 Brand O 14   M
    17 Brand X  1   Z
    18 Brand X 20   Z
    19 Brand Y  3   Z
    20 Brand Z  4   Z
    

    数据

    > dput(df)
    structure(list(ID = 1:20, brand = c("Brand X", "Brand B", "Brand Y", 
    "Brand Z", "Brand O", "Brand O", "Brand O", "Brand A", "Brand B",
    "Brand A", "Brand N", "Brand A", "Brand C", "Brand O", "Brand M",
    "Brand N", "Brand M", "Brand M", "Brand C", "Brand X")), class = "data.frame", row.names = c(NA,
    -20L))
    

    【讨论】:

      【解决方案3】:

      这是你想要的吗:

      A <- list("Brand A", "Brand B", "Brand C")
      M <- list("Brand M", "Brand N", "Brand O")
      Z <- list("Brand X", "Brand Y", "Brand Z")
      set.seed(123)
      v <- sample(unlist(c(A, M, Z)), 1000, TRUE)
      vn <- ifelse( v %in% A, 1, ifelse(v %in% M, 2, 3))
      table(vn)
      vn
        1   2   3
      325 302 373
      

      【讨论】:

      • 这正是我想要的,谢谢!我相信我在我的代码中切换了“v”和“A”,但这成功了。
      【解决方案4】:

      另一种使用查找表的方法。

      set.seed(25)
      brands <- c("Brand A" = "A", "Brand B" = "A",  
            "Brand C" = "A", "Brand M" = "M", "Brand N"= "N", 
            "Brand O" = "N", "Brand X" = "X", "Brand Y" = "X", 
            "Brand Z" = "X")
      v <- sample(unlist(c("Brand A", "Brand M", "Brand Z")), 1000, TRUE)
      v_new <- brands[v]
      table(v_new)
      
      
       v_new  
        A   M   X   
       334 308 358   
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-13
        • 1970-01-01
        • 1970-01-01
        • 2015-12-15
        • 1970-01-01
        • 2017-08-31
        • 1970-01-01
        相关资源
        最近更新 更多