当键有空格时 left_join 会产生 NA

Eri*_*een 4 r dplyr

我从左连接中得到了意外的 NA 模式。该数据来自本周的“整洁星期二”。

\n
library(tidyverse)\n\nbreed_traits <- readr::read_csv(\'https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2022/2022-02-01/breed_traits.csv\') %>%\n  select(Breed, `Affectionate With Family`)\n\n# A tibble: 195 \xc3\x97 2\n   Breed                         `Affectionate With Family`\n   <chr>                                              <dbl>\n 1 Retrievers (Labrador)                                  5\n 2 French Bulldogs                                        5\n 3 German Shepherd Dogs                                   5\n 4 Retrievers (Golden)                                    5\n 5 Bulldogs                                               4\n 6 Poodles                                                5\n 7 Beagles                                                3\n 8 Rottweilers                                            5\n 9 Pointers (German Shorthaired)                          5\n10 Dachshunds                                             5     \n\nbreed_rank_all <- readr::read_csv(\'https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2022/2022-02-01/breed_rank.csv\') %>%\n  select(Breed, `Rank 2013`)\n\n# A tibble: 195 \xc3\x97 2\n   Breed                         `2013 Rank`\n   <chr>                               <dbl>\n 1 Retrievers (Labrador)                   1\n 2 French Bulldogs                        11\n 3 German Shepherd Dogs                    2\n 4 Retrievers (Golden)                     3\n 5 Bulldogs                                5\n 6 Poodles                                 8\n 7 Beagles                                 4\n 8 Rottweilers                             9\n 9 Pointers (German Shorthaired)          13\n10 Dachshunds                             10  \n
Run Code Online (Sandbox Code Playgroud)\n

Breed尽管两个表中都有数据,但包含空格(例如Retrievers (Labrador))的行会导致 NA :

\n
breed_rank_all %>%\n  left_join(breed_traits, by = "Breed")\n\n# A tibble: 195 \xc3\x97 3\n   Breed                         `2013 Rank` `Affectionate With Family`\n   <chr>                               <dbl>                      <dbl>\n 1 Retrievers (Labrador)                   1                         NA\n 2 French Bulldogs                        11                         NA\n 3 German Shepherd Dogs                    2                         NA\n 4 Retrievers (Golden)                     3                         NA\n 5 Bulldogs                                5                          4\n 6 Poodles                                 8                          5\n 7 Beagles                                 4                          3\n 8 Rottweilers                             9                          5\n 9 Pointers (German Shorthaired)          13                         NA\n10 Dachshunds                             10                          5\n
Run Code Online (Sandbox Code Playgroud)\n

我检查了是否有多余的空格,但事实并非如此。我也尝试删除空格Breed然后加入,但没有。

\n

这里有些东西不等价:

\n
breed_rank_all$Breed[1]\n[1] "Retrievers (Labrador)"\n\nbreed_traits$Breed[1]\n[1] "Retrievers (Labrador)"\n\nbreed_rank_all$Breed[1] == breed_traits$Breed[1]\n[1] FALSE\n
Run Code Online (Sandbox Code Playgroud)\n

更新

\n

区别c2 a0在于20??

\n
iconv(breed_rank_all$Breed[1], toRaw = TRUE)\n[[1]]\n [1] 52 65 74 72 69 65 76 65 72 73 20 28 4c 61 62 72 61 64 6f 72 29\n\n> iconv(breed_traits$Breed[1], toRaw = TRUE)\n[[1]]\n [1] 52 65 74 72 69 65 76 65 72 73 c2 a0 28 4c 61 62 72 61 64 6f 72 29\n
Run Code Online (Sandbox Code Playgroud)\n

使用stringi::stri_enc_toascii

\n
> stringi::stri_enc_toascii(breed_traits$Breed[1])\n[1] "Retrievers\\032(Labrador)"\n\n> stringi::stri_enc_toascii(breed_rank_all$Breed[1])\n[1] "Retrievers (Labrador)"\n
Run Code Online (Sandbox Code Playgroud)\n

这似乎可以修复它:

\n
breed_traits <- breed_traits %>%\n  mutate(Breed = stringi::stri_enc_toascii(Breed),\n         Breed = gsub("\\\\\\032", " ", Breed)) \n
Run Code Online (Sandbox Code Playgroud)\n

Kat*_*Kat 5

我发现了这个问题。凭着直觉,我调查了空​​白。

# space that isn't a space (like non-breaking space?)
utf8::utf8_print(breed_traits$Breed[1], utf8 = FALSE)
# [1] "Retrievers\u00a0(Labrador)"
# this is a non-breaking space
Run Code Online (Sandbox Code Playgroud)

您可以使用正则表达式替换不间断空格。

(replSp = str_replace_all(string = breed_traits$Breed[1],
                pattern = "[[:space:]]",
                replacement = " ")) 
# [1] "Retrievers (Labrador)" 

breed_rank_all$Breed[[1]] == replSp
# [1] TRUE 
Run Code Online (Sandbox Code Playgroud)

按照要求...

要替换数据框中的所有不间断空格:

breed_traits <- breed_traits %>% 
   mutate(Breed = str_replace_all(string = Breed, 
                                  pattern = "[[:space:]]", 
                                  replacement = " "))
Run Code Online (Sandbox Code Playgroud)