【问题标题】:How to recode multiple values in vector into one value?如何将向量中的多个值重新编码为一个值?
【发布时间】:2019-07-12 04:54:24
【问题描述】:

我有一个问题,我的data.frame 由于数据源不同而包含不同的属性。例如,state 列实际上具有相同的状态,但表示形式不同。请注意,我的实际数据未使用美国各州。

    df <- data.frame(Names=c("Adam", "Mark", "Dahlia", "Jeff", "Derek", 
                             "Arnold", "Sheppard", "Dwayne", "Nichols", "Shane"), 
                     Age=c(27, 28, 29, 37, 26, 22, 29, 34, 31, 30), 
                     States=c("AL", "Alaska", "Alabama", "WI", 
                              "Wisconsin", "AZ", "Arizona", "AL", "WI", "AK"))

我正在尝试将 AL、WI、AZ 和 AK 等值分别重新编码为 Alabama、Wisconsin、Arizona 和 Alaska。

到目前为止,我遇到了:

    case_when(

        df$States == "AL" ~ "Alabama",
        df$States == "AK" ~ "Alaska",
        df$States == "WI" ~ "Wisconsin",
        df$States == "AZ" ~ "Arizona",
    )

它给了我输出:

     [1] "Alabama"   NA          NA          "Wisconsin" NA    "Arizona" NA         
     [8] "Alabama"   "Wisconsin" "Alaska"

我不想要 NA 值所以我所做的是:

    case_when(

      df$States == "AL" ~ "Alabama",
      df$States == "Alabama" ~ "Alabama",
      df$States == "AK" ~ "Alaska",
      df$States == "Alaska" ~ "Alaska",
      df$States == "WI" ~ "Wisconsin",
      df$States == "Wisconsin" ~ "Wisconsin",
      df$States == "AZ" ~ "Arizona",
      df$States == "Arizona" ~ "Arizona",

    )

它给了我想要的输出,但我认为有更简单的方法可以做到这一点。

我正在考虑循环,因为稍后我想把它变成伪代码。但是,我对如何执行此操作没有任何想法。非常感谢大家在这里提供帮助。

谢谢。

【问题讨论】:

    标签: r replace recode


    【解决方案1】:

    您可以将 dplyr 的 recode 函数与命名向量一起使用。我使用setNames 创建一个命名字符向量(类似于键值对),但您可以使用您拥有的任何数据创建向量。使用您的示例,我们可以设置一些键和值:

    keys <- state.abb # the abbreviations you want to replace
    vals <- state.name # the replacement values
    keysvals <- setNames(vals, keys) # create named vector
    

    现在拨打recode。确保使用!!! 取消引用和拼接:

    library(dplyr)
    
    df$States <- recode(df$States, !!!keysvals)
    

    哪个会返回:

          Names Age    States
    1      Adam  27   Alabama
    2      Mark  28    Alaska
    3    Dahlia  29   Alabama
    4      Jeff  37 Wisconsin
    5     Derek  26 Wisconsin
    6    Arnold  22   Arizona
    7  Sheppard  29   Arizona
    8    Dwayne  34   Alabama
    9   Nichols  31 Wisconsin
    10    Shane  30    Alaska
    

    【讨论】:

    • 谢谢@gersht。这真的很有帮助。我的另一个问题是,keysvals 的长度必须相同吗?因为,我的数据是我想将例如MYMalaysian 更改为MalaysiaSGSingaporean 更改为Singapore。我担心的是,有时keys 中有多个属性使用不同的缩写,但我想将其更改为一个相同的名称。
    • @mojek 它们的长度必须相同,但鉴于您的示例,这应该不是问题。您所要做的就是为每个可能的键添加多个键值对,其中的值只是重复的。例如你可以做keysvals &lt;- c(MY=Malaysia, Malaysian=Malaysia, SG = Singapore, Singaporean = Singapore)
    【解决方案2】:

    如果您打算匹配美国州名,我们可以使用内置向量 state.abbstate.name 进行匹配和替换。

    inds <- match(df$States, state.abb)
    df$States[which(!is.na(inds))] <- state.name[na.omit(inds)]
    
    df
    #       Names Age   States
    #1      Adam  27   Alabama
    #2      Mark  28    Alaska
    #3    Dahlia  29   Alabama
    #4      Jeff  37 Wisconsin
    #5     Derek  26 Wisconsin
    #6    Arnold  22   Arizona
    #7  Sheppard  29   Arizona
    #8    Dwayne  34   Alabama
    #9   Nichols  31 Wisconsin
    #10    Shane  30    Alaska
    

    您还可以通过使用%in% 来减少case_when 的长度,它可以比较多个向量,而不仅仅是使用== 的一个向量

    library(dplyr)
    
    df %>%
      mutate(States = case_when(States %in% c("AL", "Alabama") ~ "Alabama", 
                                States %in% c("AK", "Alaska")~ "Alaska", 
                                States %in% c("WI", "Wisconsin")~ "Wisconsin", 
                                States %in% c("AZ", "Arizona")~ "Arizona", 
                                 TRUE ~ NA_character_))
    

    【讨论】:

    • 谢谢。但我的数据实际上没有使用美国各州。
    • @mojek ok..在这种情况下,您可以使用case_when 答案。这也与stackoverflow.com/questions/7547597/… 非常相似,看看你是否可以使用那里的任何答案。
    猜你喜欢
    • 1970-01-01
    • 2021-07-08
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    相关资源
    最近更新 更多