2014-01-07 64 views
0

我有两行和每列包含一个字符,这大致是这样的20列data.frame(列蜷缩在这里为清楚起见):匹配中的R模式

 Cols 1-20 
    row1 ghuytuthjilujshdftgu 
    row2 ghuytuthjilujshdftgu 

我想机制,用于从位置10开始逐个字符(逐列)比较这两个字符串并向外扫描,返回匹配字符的数量,直到遇到第一个差异。在这种情况下,显然两行都是相同的,所以答案是20.重要的是,即使它们完全相同,就像上面的情况一样,不应该有错误消息(它应该被返回) 。

利用该替代示例中,答案应为12:

Cols 1-20 
row1 ghuytuthjilujshdftgu 
row2 XXXXXXXXjilujshdftgu 

下面是一些代码,以产生数据帧:

r1 <- "ghuytuthjilujshdftgu" 
r2 <- "ghuytuthjilujshdftgu" 
df1 <- as.data.frame(rbind(unlist(strsplit(r1, "")), unlist(strsplit(r1, "")))) 

r1 <- "ghuytuthjilujshdftgu" 
r2 <- "XXXXXXXXjilujshdftgu" 
df1 <- as.data.frame(rbind(unlist(strsplit(r1, "")), unlist(strsplit(r1, "")))) 

编辑。

该对象的类别的是data.frame并且它是subsettable-昏暗= 2,20(各列/字符是在其自己的访问)

+4

请提供一个可重现的例子。这是一个矩阵吗?这是一列数据框吗? –

+0

嘿..它是一个data.frame(我更新了anser)..这有帮助吗? – user3069326

+0

我删除我的答案,因为它不清楚你在问什么。 – agstudy

回答

0

下面是拆分DF成两片的答案(从中心向左和向右,重新排序左边,以便从中心到第一个值),然后使用cumsum和NA计算长度,以便cumsum一旦出现不匹配就变为NA,然后找到最高索引值不是NA来表示从中心开始的最长拉伸而没有不匹配。

sim_len <- function(df, center=floor(ncol(df)/2)) { 
    dfs <- list(df[, max(center, 1):1, drop=F], df[, center:ncol(df), drop=F]) 
    df.count <- lapply(dfs, function(df) { 
    diff <- cumsum(ifelse(df[1, ] == df[2, ], 1, NA_integer_)) 
    diff[max(which(!is.na(diff)))] 
    }) 
    max(0L, sum(unlist(df.count)) - 1L) 
} 

这里是运行它(as.data.frame企业只是从创建的字符串数据帧的一些例子。请注意,“中心”列中的最后一行计算两次,因此-1L该功能。

r1 <- "ghuytuthjilujshdftgu" 
r2 <- "ghuytuthjilujshdftgu" 
df1 <- as.data.frame(rbind(unlist(strsplit(r1, "")), unlist(strsplit(r1, "")))) 
sim_len(df1) 
# [1] 20 

r1 <- "ghuytut3jilujshdftgu" 
r2 <- "ghuytuthjilujshdftgu" 
df2 <- as.data.frame(rbind(unlist(strsplit(r1, "")), unlist(strsplit(r2, "")))) 
sim_len(df2) 
# [1] 12 

r1 <- "ghuytut3jilujshdftgu" 
r2 <- "ghuytuthjilujxhdftgu" 
df3 <- as.data.frame(rbind(unlist(strsplit(r1, "")), unlist(strsplit(r2, "")))) 
sim_len(df3) 
# [1] 5 

r1 <- "ghuytut3xilujshdftgu" 
r2 <- "ghuytuthjixujxhdftgu" 
df4 <- as.data.frame(rbind(unlist(strsplit(r1, "")), unlist(strsplit(r2, "")))) 
sim_len(df4) 
# [1] 1 

,报告左,右计数的变化。请注意,“中心”进行计数左,右,这样的总和左+右比什么报道1大原创功能:

sim_len2 <- function(df, center=floor(ncol(df)/2)) { 
    dfs <- list(left=df[, max(center, 1):1, drop=F], right=df[, center:ncol(df), drop=F]) 
    vapply(dfs, 
    function(df) { 
     diff <- cumsum(ifelse(df[1, ] == df[2, ], 1, NA_integer_)) 
     diff[max(which(!is.na(diff)))] 
     }, 
     numeric(1L) 
) } 
sim_len2(df1) 
# left right 
# 10 11 
sim_len2(df4, 4) 
# left right 
# 4  4 
+0

@BroadieG工作......但你能否以某种方式实现它不会自动在字符串中心自动启动,而是在给定的位置? – user3069326

+0

@BroadieG我可以用任何随机位置重新定位中心吗?是否有机会展示不仅最终结果,而且还有展示左侧和右侧匹配的数量? – user3069326

+0

@ user3069326,我修改了代码以添加可选的'center'参数。请注意,这并不会检查您的“中心”是否合理(即在'df'的#列中)。如果这适用于您,请将q标记为已回答,但我不知道您是否可以保留。 – BrodieG