R添加一个列,其中包含若干子字符串在所有列中出现的次数

lsmd5eda  于 2023-07-31  发布在  其他
关注(0)|答案(2)|浏览(93)

我有一个这样的dataframe:

df<-data.frame(x = c("T302928", "C0293", "G402928", "T30294", "S40298"),
               y = c("B40292", "I980", "B40928", "C203948", "V308283"),
               z = c("C0255", "V302939", "N02938", "R09282", "B02938"))

字符串
并且需要创建一个列,计数某些子字符串在每一行的每一列中开始一个值的次数,以得到这样的DF。例如,如果我正在搜索以字符“T30”、“C 02”和“V30”开头的值,我会得到这样的df:

x       y       z count_all
1 T302928  B40292   C0255         2
2   C0293    I980 V302939         2
3 G402928  B40928  N02938         0
4  T30294 C203948  R09282         1
5  S40298 V308283  B02938         1


我得到的最接近的是这样的:
df$count_all <- apply(df, 1, function(x) length(which(x %in% c("T03", "C02", "V30"))))
但是我不知道如何在which()函数中搜索多个子字符串。
提前感谢任何建议!

tcomlyy6

tcomlyy61#

%in%不做子字符串匹配(这是Python的事情)。
您可以使用grepl

rowSums(sapply(df, grepl, pattern = "^(T30|C02|V30)"))
# [1] 2 2 0 1 1

字符串
如果所有模式都是3字符串,那么可以这样做:

apply(df, 1, function(x) length(which(substring(x, 1, 3) %in% c("T30", "C02", "V30"))))
# [1] 2 2 0 1 1


虽然它的工作原理有点像sapply,但我倾向于在帧上小心使用apply,因为它在操作之前将整个东西转换为matrix。这可能会产生后果,最明显的是它可能会更昂贵(数据量大得多)。另一方面,sapply(和lapply)可以按列方式工作,这会减少很多工作。使用此操作,sapply将返回logicalmatrix,然后我们可以在它上使用rowSums来提供您要查找的行数。

jei2mxaa

jei2mxaa2#

你可以用across试试下面的代码

library(tidyverse)

df %>% rowwise() %>% 
  mutate(across(everything(), ~ sum(trimws(str_extract(.x,'^\\w{1,1}\\d{2,2}')) %in% var), .names = 'new_{col}'),
         count=rowSums(across(starts_with('new')))) %>% select(-c(starts_with('new')))
# A tibble: 5 × 4
# Rowwise: 
  x       y       z       count
  <chr>   <chr>   <chr>   <dbl>
1 T302928 B40292  C0255       2
2 C0293   I980    V302939     2
3 G402928 B40928  N02938      0
4 T30294  C203948 R09282      1
5 S40298  V308283 B02938      1

相关问题