根据列R / dplyr中的“复杂”字符串过滤行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据列R / dplyr中的“复杂”字符串过滤行相关的知识,希望对你有一定的参考价值。

我能够使用特定列中的字符串过滤我的数据集,这里是一个示例数据集以及我是如何做到的。

ID = c(1, 2, 3, 4)
String = c("Y N No", "Y", "Y No", "Y N")
df = data.frame(ID, String)

问题是 - 我只想选择其中包含N的ID - 或 - 其中没有N的ID。

df_2 <- dpylr::filter(df, !grepl('N', String)) 

Output: [2]  [Y]

这将用N过滤出ID,但它也会删除N的所有情况(包括那些有'否'的情况。我是R的新手,所以我很抱歉,如果这只是我不理解语法 - 但我无法想到这一点出。

我也可以尝试将字符串解析为单个列,然后根据它进行选择 - 无论如何我都需要这样做以便以后分析。下面是我用来实现此目的的代码。

df_2 <- df%>%mutate(String=gsub("\b([A-Za-z]+)\b","\11",String),
          name=str_extract_all(String,"[A-Za-z]+"),
          value=str_extract_all(String,"\d+"))%>%
unnest()%>%spread(name,value,fill=0)

这给了我

Output: 
ID<chr>  String<chr>   N<chr>  No <chr>   Y<chr>
1         Y1 N1 No1      1        1         1
2         Y1             0        0         1
3         Y1 No1         0        1         1
4         Y1 N1          1        0         1

这样我就可以根据N是零还是一个来选择我的行 - 但是,当我这样做时R不喜欢,我不明白为什么。

感谢您提供的任何帮助。

编辑:这是我的实际数据的示例。在我的问题中,我可能已经过度简化了。

m/z             Column

241             C15 H22 O Na                
265             C15 H15 N5 
301             C16 H22 O4 Na 
335             C19 H20 O4 Na           
441             C26 H42 O4 Na 

我的目标是过滤掉列中的所有N(它们的范围从N,N1,N4等)

答案
ID = c(1, 2, 3, 4)
String = c("Y N No", "Y", "Y No", "Y N")
df = data.frame(ID, String)
df %>% filter(!grepl("(N\d+|N\s)", String))

Output: [Y] [Y No]

@MauritsEvers的这个答案也适用于第二段中更复杂的数据集 - 其中也可能在N之后的数字(如N2或N10)也将包含在参数中。去掉 ”!”包括“N”。

另一答案

我认为你的第二种方法是要走的路,特别是如果要拆分下游分析的列。它(imo)也符合“整洁”的要求。我还建议标准化String变量。是/ Y,否/ N是不可接受的。

tidyr包有两个很好的功能,这个separategather

library(dplyr)
library(tidyr)

ID = c(1, 2, 3, 4)
String = c("Y N No", "Y", "Y No", "Y N")
String <- gsub(pattern = "No", "N", String)
df = data.frame(ID, String)

#Separate the String var
df_sep <- separate(df, col = String, into = c("R1", "R2", "R3"), sep = " ", extra = "merge")
#gather the columns
df_gat <- gather(df_sep, Cols, StrValue, R1:R3, -ID) 
#filter
filter(df_gat, StrValue == "N" | StrValue != "N")

这是我修改后的答案:

library(dplyr)
library(tidyr)
#Separate the String var
df_sep <- separate(df, col = Column, into = c("E1", "E2", "E3", "E4"), sep = " ", extra = "merge")
#gather the columns, long data format
gather(df_sep, Cols, Element, E1:E4, -m.z) %>% select(m.z, Element) -> df_gat
#filter
filter(df_gat, !grepl("^N$|N\d", df_gat$Element))

它生成一个与过滤函数配合良好的长数据集。您以前的数据很广(有点)。我建议将钠的符号改为其他东西,如果Na(钠)转化为NA,你可能会遇到麻烦。

另一答案

您可能希望使用sub替换""以匹配"N(\d{1,3}|\s|$)"的任何模式,意味着“N”后跟1-3个数字之一或空格或字符串结尾。

我不认为你会使用过滤,因为我理解英文描述,你想从字符值中删除特定的模式。我想象这些是化学符号,N是氮,Na是钠。

以上是关于根据列R / dplyr中的“复杂”字符串过滤行的主要内容,如果未能解决你的问题,请参考以下文章

使用 dplyr 根据列值对 R 中的值求和

r 使用R中的dplyr过滤包含特定字符串的行

基于存储为R w / dplyr mutate()中的向量的列索引连接data.frame字符列?

R语言dplyr包数据过滤(filter)基于not in规则实战(not in Filter):基于单数据列not in规则过滤数据行基于多数据列not in规则过滤数据行

R:dplyr 有条件地汇总并重新编码列中的值

根据用户的输入创建列联表 - R Shiny