R 删除带有条件的某些行

R 删除带有条件的某些行,r,regex,R,Regex,下面是我工作的数据示例,它由两列V1和V2组成 V1 V2 1 A415Z A415Z 1.010 2 A415J A415Z 0.960 3 B416X A415Z 0.980 4 B416Z A415Z 0.990 5 B416J A415Z 1.020 6 B416M A415Z 1.085 7 B416P A415Z 6.380 8 B416W A415Z 0.995 9 D420R A4

下面是我工作的数据示例,它由两列V1和V2组成

         V1        V2
1   A415Z A415Z   1.010
2   A415J A415Z   0.960
3   B416X A415Z   0.980
4   B416Z A415Z   0.990
5   B416J A415Z   1.020
6   B416M A415Z   1.085
7   B416P A415Z   6.380
8   B416W A415Z   0.995
9   D420R A415Z   0.995
10  D420H A415Z   0.975
11  B416X B416X   0.950
12  B416Z B416X   0.960
13  B416J B416X   0.990
14  B416M B416X   1.055
在第一列“V1”中,我想删除两个单词以相同字符开头的行。 例如:在第一、第二和最后四行中,元素为:A415Z A415Z、A415J A415Z、B416X B416X, B416Z B416X、B416J B416X、B416M B416X。因此,输出应该与下面给出的一样

         V1         V2
1   B416X A415Z   0.980
2   B416Z A415Z   0.990
3   B416J A415Z   1.020
4   B416M A415Z   1.085
5   B416P A415Z   6.380
6   B416W A415Z   0.995
7   D420R A415Z   0.995
8   D420H A415Z   0.975
我如何在这里使用正则表达式?(或)如果有更好的方法,建议会有所帮助

使用tidyr:

library(dplyr)
library(tidyr)

df1 %>%
  separate(V1, c("V1_1", "V1_2"), remove = FALSE) %>% 
  mutate(V1_1 = substr(V1_1, 1, 1),
         V1_2 = substr(V1_2, 1, 1)) %>% 
  filter(V1_1 != V1_2) %>% 
  select(V1, V2)

将第一列分隔为2,然后使用子字符串进行比较,以获取第一个字符,并比较它们是否与筛选器相同。

另一种可能性是,使用
stringr
包提取并比较第一个字母

library(stringr)

df[unlist(lapply(str_extract_all(df$V1, '(?<=\\b)([A-z])'), function(i)
                                                             length(unique(i)) != 1)),]

#            V1    V2
#3  B416X A415Z 0.980
#4  B416Z A415Z 0.990
#5  B416J A415Z 1.020
#6  B416M A415Z 1.085
#7  B416P A415Z 6.380
#8  B416W A415Z 0.995
#9  D420R A415Z 0.995
#10 D420H A415Z 0.975

或者一个
基本R
选项是匹配一个或多个数字(
\\d+
),后跟一个或多个非空格(
\\s+
),后跟零个或多个空格(
\\s*
),将其替换为空格(
),然后匹配重复字符(
()\\1+
),在第二个
gsub
中用空格替换它,获取字符数(
nchar
),检查它是否不等于0,即如果有像“AA”这样的元素,它将被删除,而带有
BA
DA
的元素将被保留)以对行进行子集划分

df1[nchar(gsub("(.)\\1+", "", gsub("\\d+\\S+\\s*", "", df1$V1)))!=0,]
#          V1    V2
#3  B416X A415Z 0.980
#4  B416Z A415Z 0.990
#5  B416J A415Z 1.020
#6  B416M A415Z 1.085
#7  B416P A415Z 6.380
#8  B416W A415Z 0.995
#9  D420R A415Z 0.995
#10 D420H A415Z 0.975
还是为了安全

df1[nchar(gsub("(.)\\1+", "", gsub("\\b(\\S)\\S+\\s*", "\\1", df1$V1))) !=0,]

该方法工作正常,但会产生警告。警告消息:289个位置的值太多:1、2、3、4、5、6、7、8、9、10、11、12、13、14、15、16、17、18、19、20、@AmrithaAmarnath使用示例数据,此解决方案有效,请更新输入数据以重现“警告”。您应该将问题分成两部分:1。如何检测两个单词是否以相同字符开头。2.我怎样才能只保留那些与某个谓词匹配的行。@Sotos:regex可以“简化”为
\\b[a-Za-z]
(甚至
\\b\\p{L}
),因为单词边界本身就是一个零宽度断言,
[a-z]
@WiktorStribiżew感谢您的链接和建议。非常有用。
df1[nchar(gsub("(.)\\1+", "", gsub("\\b(\\S)\\S+\\s*", "\\1", df1$V1))) !=0,]