根据"复杂"过滤行列R / dplyr

时间:2018-03-01 01:50:32

标签: 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的所有情况(包括那些有&#39; No&#39;。我是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等)

3 个答案:

答案 0 :(得分:2)

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)也将包含在参数中。删除&#34;!&#34;包括&#34; N&#34;。

答案 1 :(得分:0)

我认为您的第二种方法是要走的路,特别是如果要拆分下游分析列。它也(imo)满足&#34; tidy&#34;要求。我还建议标准化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,你可能会遇到麻烦。

答案 2 :(得分:0)

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

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