我正在寻找如何在R中选择在两列中具有部分匹配或不匹配的行。我的数据集(作为示例)如下所示:
df = data.frame(plot1 = c("ABX_15", "BHE_05", "ABX_15"),
plot2 = c("AB6_15", "JKS_05", "JKS_05"),
value = c(0.4, 0.45, 0.34))
我想为plot1
和plot2
创建仅包含_05
和_15
“匹配”对的子集。这样就可以是示例中的第一行或第二行。我还需要只选择plot1
和plot2
中具有不匹配的行,即第3行。匹配一个不匹配仅参考情节名称的第二部分。
我找到了部分选择和根据列选择某些行的解决方案,但我无法将两者结合使用。
我期待数据集的3个子集:一个匹配_05
另一个匹配_15
,另一个匹配不匹配。
答案 0 :(得分:1)
另一个解决方案是使用sub
从两个变量中删除(包括)下划线之前的所有内容,然后将这些sub
语句与==
进行比较,以创建逻辑索引向量: / p>
idx <- sub('.*\\_', '', df$plot1) == sub('.*\\_', '', df$plot2)
现在,您可以使用该向量对df
进行分组。 df[idx,]
给出:
plot1 plot2 value
1 ABX_15 AB6_15 0.40
2 BHE_05 JKS_05 0.45
要解决不匹配问题,您可以使用df[!idx,]
:
plot1 plot2 value
3 ABX_15 JKS_05 0.34
根据您的要求更新,您可以创建索引,以便在15
或05
上进行匹配,如下所示:
idx15 <- sub('.*\\_', '', df$plot1) == '15' & sub('.*\\_', '', df$plot2) == '15'
idx05 <- sub('.*\\_', '', df$plot1) == '05' & sub('.*\\_', '', df$plot2) == '05'
然后可以将这些用于子集df
,如上所示(例如df[idx15,]
)。要获得不匹配:df[!idx05 & !idx15,]
(或使用上面的方法)。
答案 1 :(得分:0)
Fist按照模式_
填充了名称。我在这里使用str_split
包中的函数stringr
。结果是一个列表。您现在可以提取名称的第二部分。取消列出后,您可以将结果添加到数据框df
:
df$p1 <- unlist(lapply(str_split(df$plot1, "_"), "[", 2))
df$p2 <- unlist(lapply(str_split(df$plot2, "_"), "[", 2))
对于基本R解决方案,您可以使用strspilt
功能。请注意,您必须从中创建一个字符向量。
unlist(lapply(strsplit(as.character(df$plot1), "_"), "[", 2))
结果:
df[df$p1 == df$p2, ]
plot1 plot2 value p1 p2
1 ABX_15 AB6_15 0.40 15 15
2 BHE_05 JKS_05 0.45 05 05
对于不匹配使用:
df[df$p1 != df$p2, ]
plot1 plot2 value p1 p2
3 ABX_15 JKS_05 0.34 05 15