R中gsub序列的累积应用
Cumulative application of a gsub sequence in R
我正在从事一个处理国际象棋游戏的项目。在对数据进行一些处理后,我需要获得特定位置的 FEN (https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation) 符号。我已经为每一块 FEN 编码编写了代码,但是我很难编码代表未被占用的连续方块数的字符。
以FEN代码为例:
"rnbq1rk1/pppp1ppp/1b11pn11/11111111/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
每个1代表棋盘内一个未被占据的方格。因此,例如:11111111
告诉我们棋盘内的这一行没有被棋子占据。
问题是,使用 FEN 作为输入绘制棋盘的 R 包不喜欢这种表示法,他们想要更简洁、原始的表示法,其中所有 1
都由一个字符表示:总和所有这些连续的 1
秒。对于前面的例子,那将是:
"rnbq1rk1/pppp1ppp/1b2pn2/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w KQkq c6 0 2"
注意,例如11111111
序列被8
代替,所有连续1
s的总和
我试过使用 mapply
和 gsub
来完成替换,但它一次一个地迭代应用模式替换对的字符串。结果如下:
代码:
pattern <- c("11111111","1111111","111111","111111","1111","111","11")
replacement <- c("8","7","6","5","4","3","2")
FENCodeToBeChanged <- "rnbq1rk1/pppp1ppp/1b11pn11/11111111/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
mapply(gsub,pattern,replacement,FENCodeToBeChanged)
结果:
11111111
"rnbq1rk1/pppp1ppp/1b11pn11/8/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
1111111
"rnbq1rk1/pppp1ppp/1b11pn11/71/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
111111
"rnbq1rk1/pppp1ppp/1b11pn11/611/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
111111
"rnbq1rk1/pppp1ppp/1b11pn11/511/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
1111
"rnbq1rk1/pppp1ppp/1b11pn11/44/11PP4/41NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
111
"rnbq1rk1/pppp1ppp/1b11pn11/3311/11PP31/311NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
11
"rnbq1rk1/pppp1ppp/1b2pn2/2222/2PP22/221NP1/PP2PPBP/RNBQ1RK1 w KQkq c6 0 2"
如您所见,它进行替换,但一次一个,对于下一个模式替换对,它从原始字符串开始,它不会按照我在模式中指定的顺序累积它们- 替换向量。
我已经尝试过 here and 中描述的策略,但它们也没有奏效。正如它在最后 link 中提到的,我试图不惜一切代价避免循环 gsubs 来完成工作,因为它看起来效率很低。
对如何进行有任何想法吗?
谢谢!
mapply
的问题在于它正在为每次替换查找 FEN 字符串的新副本,这不是您所需要的。我认为你可以使用 Reduce
心态:
(顺便说一句,你的“5”模式有 6 个,这解决了这个问题。)
pattern <- c("11111111","1111111","111111","11111","1111","111","11")
Reduce(function(txt, ptn) gsub(ptn, as.character(nchar(ptn)), txt), pattern, init=FENCodeToBeChanged)
# [1] "rnbq1rk1/pppp1ppp/1b2pn2/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w KQkq c6 0 2"
为了能够减少多个参数需要做一些工作,通常是沿着成对列表等进行迭代。对于 this 问题,很容易用它的长度替换模式而不是包含另一个字符串向量,ergo nchar(ptn)
。 (技术上 as.character(.)
不是必需的,因为 gsub
会隐式转换它,但我想有点“声明性”,因为这就是我想要的。R 中有许多工具在这方面不太确定方式(例如,ifelse
)。样式。)
我正在从事一个处理国际象棋游戏的项目。在对数据进行一些处理后,我需要获得特定位置的 FEN (https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation) 符号。我已经为每一块 FEN 编码编写了代码,但是我很难编码代表未被占用的连续方块数的字符。
以FEN代码为例:
"rnbq1rk1/pppp1ppp/1b11pn11/11111111/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
每个1代表棋盘内一个未被占据的方格。因此,例如:11111111
告诉我们棋盘内的这一行没有被棋子占据。
问题是,使用 FEN 作为输入绘制棋盘的 R 包不喜欢这种表示法,他们想要更简洁、原始的表示法,其中所有 1
都由一个字符表示:总和所有这些连续的 1
秒。对于前面的例子,那将是:
"rnbq1rk1/pppp1ppp/1b2pn2/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w KQkq c6 0 2"
注意,例如11111111
序列被8
代替,所有连续1
s的总和
我试过使用 mapply
和 gsub
来完成替换,但它一次一个地迭代应用模式替换对的字符串。结果如下:
代码:
pattern <- c("11111111","1111111","111111","111111","1111","111","11")
replacement <- c("8","7","6","5","4","3","2")
FENCodeToBeChanged <- "rnbq1rk1/pppp1ppp/1b11pn11/11111111/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
mapply(gsub,pattern,replacement,FENCodeToBeChanged)
结果:
11111111
"rnbq1rk1/pppp1ppp/1b11pn11/8/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
1111111
"rnbq1rk1/pppp1ppp/1b11pn11/71/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
111111
"rnbq1rk1/pppp1ppp/1b11pn11/611/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
111111
"rnbq1rk1/pppp1ppp/1b11pn11/511/11PP1111/11111NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
1111
"rnbq1rk1/pppp1ppp/1b11pn11/44/11PP4/41NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
111
"rnbq1rk1/pppp1ppp/1b11pn11/3311/11PP31/311NP1/PP11PPBP/RNBQ1RK1 w KQkq c6 0 2"
11
"rnbq1rk1/pppp1ppp/1b2pn2/2222/2PP22/221NP1/PP2PPBP/RNBQ1RK1 w KQkq c6 0 2"
如您所见,它进行替换,但一次一个,对于下一个模式替换对,它从原始字符串开始,它不会按照我在模式中指定的顺序累积它们- 替换向量。
我已经尝试过 here and
对如何进行有任何想法吗?
谢谢!
mapply
的问题在于它正在为每次替换查找 FEN 字符串的新副本,这不是您所需要的。我认为你可以使用 Reduce
心态:
(顺便说一句,你的“5”模式有 6 个,这解决了这个问题。)
pattern <- c("11111111","1111111","111111","11111","1111","111","11")
Reduce(function(txt, ptn) gsub(ptn, as.character(nchar(ptn)), txt), pattern, init=FENCodeToBeChanged)
# [1] "rnbq1rk1/pppp1ppp/1b2pn2/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w KQkq c6 0 2"
为了能够减少多个参数需要做一些工作,通常是沿着成对列表等进行迭代。对于 this 问题,很容易用它的长度替换模式而不是包含另一个字符串向量,ergo nchar(ptn)
。 (技术上 as.character(.)
不是必需的,因为 gsub
会隐式转换它,但我想有点“声明性”,因为这就是我想要的。R 中有许多工具在这方面不太确定方式(例如,ifelse
)。样式。)