R - 有没有办法比较列字符串之间的各个项目?

问题描述 投票:0回答:1

我有一个数据集,并试图比较字符串中的任何值是否出现在同一行的一组列中的任何一个中。

数据的子集如下所示:

df <- data.frame(ID=c(1,2,3,4,5), 
                 A=c("A1","A3","A5","A7","A8"),
                 B=c("B3","B6","B8","B11","B20"),
                 C=c("C2","C1","C2",NA,"C3"),
                 D=c("D7","D11","D1","D5",NA),
                 X=c("A1,B7,B11,C2","A2,A5","A1,B5,B8,D3","","A9,B11,B20,C3"))

我想看看在一行中X中的任何元素(用逗号分隔)是否出现在A-D列中,并输出匹配的值。

在此示例中,理想情况下输出将是另一列“Z”,其值:

Z=c("A1,C2",NA,"B8",NA,"B20,C3")

关于如何解决这个问题,我的第一个想法是为每一行创建两个向量,一个包含 X 的各个项目,一个包含其他列的各个项目,然后比较向量中的值,但在尝试中陷入困境将每个单元格转换为向量而不是列。

我想知道

str_detect
是否有用,但到目前为止还没有弄清楚如何比较单个项目而不是整个字符串,并且它会针对缺失值(其中有很多)显示一条错误消息

这是我最近的尝试,但它没有单独比较各个项目。

mutate(df,unite(df[2:5],Y,sep=",",na.rm=TRUE)) %>%
  select(X,Y) %>%
  mutate(Z=str_detect(Y,X))

我的想法可能完全错误,因此非常感谢您的任何想法或指示。

r string compare vectorization
1个回答
0
投票

您可以围绕

intersect()
构建它,以获取两个输入向量中都存在的项目,当您切换到按行分组时,您将获得第一个带有
c(across(A:D))
的输入向量和第二个带有
str_split(X, ",", simplify = TRUE)
的输入向量,然后您可以使用
str_c()
paste0()
来获取单个字符串:

library(stringr)
library(dplyr)

df <- data.frame(ID=c(1,2,3,4,5), 
                 A=c("A1","A3","A5","A7","A8"),
                 B=c("B3","B6","B8","B11","B20"),
                 C=c("C2","C1","C2",NA,"C3"),
                 D=c("D7","D11","D1","D5",NA),
                 X=c("A1,B7,B11,C2","A2,A5","A1,B5,B8,D3","","A9,B11,B20,C3"))

df |>
  rowwise() |>
  mutate(Z = intersect(
    c(across(A:D)), 
    str_split(X, ",", simplify = TRUE)
    ) |> str_c(collapse = ",")) |>
  ungroup()
#> # A tibble: 5 × 7
#>      ID A     B     C     D     X               Z       
#>   <dbl> <chr> <chr> <chr> <chr> <chr>           <chr>   
#> 1     1 A1    B3    C2    D7    "A1,B7,B11,C2"  "A1,C2" 
#> 2     2 A3    B6    C1    D11   "A2,A5"         ""      
#> 3     3 A5    B8    C2    D1    "A1,B5,B8,D3"   "B8"    
#> 4     4 A7    B11   <NA>  D5    ""              ""      
#> 5     5 A8    B20   C3    <NA>  "A9,B11,B20,C3" "B20,C3"

创建于 2024-01-05,使用 reprex v2.0.2

© www.soinside.com 2019 - 2024. All rights reserved.