根据列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
包有两个很好的功能,这个separate
和gather
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中的“复杂”字符串过滤行的主要内容,如果未能解决你的问题,请参考以下文章
基于存储为R w / dplyr mutate()中的向量的列索引连接data.frame字符列?
R语言dplyr包数据过滤(filter)基于not in规则实战(not in Filter):基于单数据列not in规则过滤数据行基于多数据列not in规则过滤数据行