【问题标题】:R - Using loops to search one variable with another and create new merged variableR - 使用循环搜索一个变量和另一个变量并创建新的合并变量
【发布时间】:2021-08-18 07:19:57
【问题描述】:

我只擅长 R 编码的基础知识,不知道如何进行复杂的循环。 我有一个大型数据框,其中包含一列地址和一列邮政编码(以及其他变量)。每列中有许多 NA。对于缺少 zip 和 state 或仅缺少 zip 的某些行,地址列的数据不完整。我所有的数据都来自同一个州。

我需要清理地址数据以便稍后进行地理编码。我不想省略 NA 行,因为我也将使用相同的数据框进行仅限邮政编码的分析(当我制作太多类似的对象时我也会迷路)。我在 Address 中有很多 NA,但我仍然有同一行的 Zipcode 值。

我的解决方案是:

  1. 对于 df$Address 中的每一行,如果它不是一个 NA
  2. 如果 df$Address 不以 df$Zipcode 结尾
  3. 然后将 df$Address 结合“MI”和 df$Zipcode 粘贴为新列值
  4. 删除重复的单词(仅适用于具有带状态地址但缺少 zip 的条目)

最小可重复样本:

Address <- c("1234 address", "5678 address, MI", "9012 address, MI 12345", "1111 adrus")
Zipcode <- c("67890", "56780", "12345", "12345")
df <- data.frame(Address, Zipcode)

#example dataframe
Address                   Zipcode
1234 address               67890            
5678 address, MI           56780            
9012 address, MI 12345     12345            
1111 adrus                 12345    

这是我的尝试。我也尝试了 grepl() 并得到了同样的错误。

for (i in 1:length(df$Address)) {
  if(!is.na(df$Address[i])) {
    if (!endsWith(df$Address, df$Zipcode)) {
       df$Address_cln<- paste(df$Address, df$Zipcode, sep="MI ")
    }
    else {dataZip$address_cln <- paste(dataZip$Address)
    }}}

我收到此错误:条件的长度 > 1,并且只会使用第一个元素。它将未修改的 df$Address 粘贴到新列 df$Address_cln

我试图在继续删除重复的“MI”之前对前 3 个部分进行编码,因此我的代码中不包含该部分。

我稍后会尝试以某种方式修复拼写错误的条目,因为除了帮助我上面的合并循环之外,这是一个很大的问题。 感谢您的帮助!

【问题讨论】:

    标签: r dataframe loops merge na


    【解决方案1】:

    我们可以检查“地址”是否在字符串末尾有 5 位数字,然后返回“地址”或带有“邮政编码”列的 paste (str_c)

    library(dplyr)
    library(stringr)
    df %>%
      mutate(Address2 = case_when(str_detect(Address, '\\d{5}$') ~
        Address, str_detect(Address, 'MI$') ~ str_c(Address, Zipcode, 
         sep = ' '), TRUE ~ str_c(Address, Zipcode, sep = ', MI ')))
    

    -输出

    #                 Address Zipcode               Address2
    #1           1234 address   67890  1234 address MI 67890
    #2       5678 address, MI   56780 5678 address, MI 56780
    #3 9012 address, MI 12345   12345 9012 address, MI 12345
    #4             1111 adrus   12345    1111 adrus, MI 12345
    

    【讨论】:

      【解决方案2】:

      我们可以使用一些带有正则表达式的stringr 函数:

      library(stringr)
      library(dplyr)
      df %>% 
        mutate(Address= str_remove(Address, "[0-9]*$"),
               Address= str_trim(str_remove(Address, ", MI"))) %>% 
        mutate(Address_new = str_c(Address, " MI ", Zipcode))
      

      输出:

             Address Zipcode           Address_new
      1 1234 address   67890 1234 address MI 67890
      2 5678 address   56780 5678 address MI 56780
      3 9012 address   12345 9012 address MI 12345
      4   1111 adrus   12345   1111 adrus MI 12345
      

      【讨论】:

        【解决方案3】:

        使用 Base R,我为您提供了这个解决方案,但请注意,我从您的代码中使用了 sep="MI" 的“粘贴”,您地址的第 4 个元素已经有“MI”,所以这增加了对输出有一个双重的“MI”,没有任何知识,我的猜测是它是一个状态缩写,如果数据涵盖多个状态,很可能是不正确的。

        Address <- c("1234 address", "5678 address, MI", "9012 address, MI 12345", "1111 adrus")
        Zipcode <- c("67890", "56780", "12345", "12345")
        df <- data.frame(Address, Zipcode)    
        
        df$address_cln <- apply(df,MARGIN = 1, function(df_row) {
          if(!grepl(paste0(df_row[2],"$"), df_row[1])){
            return(paste(df_row[1], df_row[2], sep=" MI "))
          }else{
            return(df_row[1])
          }
        })
        

        df

                 Address           Zipcode             address_cln
        1           1234 address   67890     1234 address MI 67890
        2       5678 address, MI   56780 5678 address, MI MI 56780
        3 9012 address, MI 12345   12345    9012 address, MI 12345
        4             1111 adrus   12345       1111 adrus MI 12345
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-02-16
          • 1970-01-01
          • 2019-01-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多