R语言 如何获取匹配字符?

yzxexxkh  于 2022-12-06  发布在  其他
关注(0)|答案(5)|浏览(192)

我试图从两个不同的向量中得到共同的字符。
示例:

x <- c("abcde")
y <- c("efghi")
df <- data.frame(x, y)

所需输出

x       y     z 
abcde   efghi     e     
lmnop   uvmxw     m

我曾经尝试过这样的方法,但结果很糟糕:

df |> mutate(m = unique(x, y))

如果有多个匹配项,则返回一个列表将非常有效。

o7jaxewo

o7jaxewo1#

str_intersect <- function(s1,s2) {
  paste0(intersect(strsplit(s1,"")[[1]],strsplit(s2,"")[[1]]),collapse = "")
}

x <- c("abcde","abc")
y <- c("efghi","b")
df <- data.frame(x, y)

library(dplyr)
df %>%
  rowwise() %>%
  mutate(m = str_intersect(x,y))
ar7v8xwq

ar7v8xwq2#

采用R基方法:

> df$z <- intersect(unlist(strsplit(df$x, "")), unlist(strsplit(df$y, "")))
> df
      x     y z
1 abcde efghi e
2 lmnop uvmxw m
  • 数据 *
structure(list(x = c("abcde", "lmnop"), y = c("efghi", "uvmxw"
), z = c("e", "m")), row.names = c(NA, -2L), class = "data.frame")
gkl3eglg

gkl3eglg3#

下面是一个tidyverse解决方案,它包含stringr中的函数,也可以处理多个常用字符:

library(stringr)
df %>%
  mutate(
    # convert `x` to alternation pattern:
    y1 = str_replace_all(x, "(?<=.)(?=.)", "|"),
    # which of `y1` are contained in `x`?:
    match = str_extract_all(y, y1)
         ) 
      x     y        y1 match
1 abcde efghi a|b|c|d|e     e
2 lmnop ovmxw l|m|n|o|p  o, m

可以通过添加%>% select(-y1)来删除y1
数据来源:

x <- c("abcde", "lmnop")
y <- c("efghi", "ovmxw")
df <- data.frame(x, y)
brgchamk

brgchamk4#

这里有一个方法,我们通过将'y'列 Package 在[]中来更新它,并添加^,这样,除了那些字符之外的所有字符都将匹配为pattern,并使用str_remove_all删除

library(stringr)
library(dplyr)
df %>%
   mutate(z = str_remove_all(x, sprintf("[^%s]", y)))
  • 输出
x     y z
1 abcde efghi e
2 lmnop uvmxw m

它还处理多个字符,

df1 %>%
    mutate(z = str_remove_all(x, sprintf("[^%s]", y)))
      x     y  z
1 abcde efghi  e
2 lmnop ovmxw mo

数据

df <- structure(list(x = c("abcde", "lmnop"), y = c("efghi", "uvmxw"
)), row.names = c(NA, -2L), class = "data.frame")
df1 <- structure(list(x = c("abcde", "lmnop"), y = c("efghi", "ovmxw"
)), class = "data.frame", row.names = c(NA, -2L))
n9vozmp4

n9vozmp45#

在函式中使用strsplitintersect,并进行一些案例行程。

strintr <- \(x) {
  o <- apply(x, 1, \(.) do.call(intersect, strsplit(., '')))
  dx <- dim(x)[1]
  if (!identical(o, dx)) length(o) <- dx
  o[lengths(o) == 0L] <- NA_character_
  if (any(lengths(o) > 1L)) lapply(o, as.list) else o
}

用法

cols <- c('x', 'y')

使用within

within(df1, foo <- strintr(df1[cols]))
#       x     y foo
# 1 abcde efghi   e
within(df2, foo <- strintr(df2[cols]))
#       x     y foo
# 1 abcde efghi   e
# 2 lmnop uvmxw   m
within(df3, foo <- strintr(df3[cols]))
#       x      y  foo
# 1 abcde defghi d, e
# 2 lmnop  uvmxw    m
within(df4, foo <- strintr(df4[cols]))
#       x   y  foo
# 1 abcde xyz <NA>
# 2 lmnop xyz <NA>
within(df5, foo <- strintr(df5[cols]))
#       x      y  foo
# 1 abcde defghi d, e
# 2 lmnop    xyz   NA

使用$

df3$foo <- strintr(df3[cols])
df3
#       x      y  foo
# 1 abcde defghi d, e
# 2 lmnop  uvmxw    m

使用dplyr::mutate

dplyr::mutate(df3, fo=strintr(df3[cols]))
#       x      y   fo
# 1 abcde defghi d, e
# 2 lmnop  uvmxw    m

**注意:**由于某种错误,这将不适用于transform

  • 数据类型:*
df1 <- data.frame(x="abcde", y="efghi")
df2 <- data.frame(x=c('abcde', 'lmnop'),
                  y=c('efghi', 'uvmxw'))
df3 <- data.frame(x=c('abcde', 'lmnop'),
                  y=c('defghi', 'uvmxw'))
df4 <- data.frame(x=c('abcde', 'lmnop'),
                  y=c('xyz', 'xyz'))
df5 <- data.frame(x=c('abcde', 'lmnop'),
                  y=c('defghi', 'xyz'))

相关问题