计算特定模式之前的唯一值的数量?

时间:2018-06-17 09:27:07

标签: r

我在数据框df$moves中有一个列,如下所示:

W1.e4 B1.d5 W2.c4 B2.e6 W3.Nc3 B3.Nf6 W4.cxd5 B4.exd5 W5.Bg5 
W1.e4 B1.d5 W2.exd5 B2.Qxd5 W3.Nc3 B3.Qa5 W4.d4 B4.Nf6 W5.Nf3 B5.c6 W6.Ne5 B6.Bf5 
W1.e4 B1.e5 W2.Nf3 B2.Nc6 W3.Bc4
W1.e4 B1.e5 W2.Nf3 B2.Nf6
W1.e4 B1.c5 W2.Nf3

我希望在字符“W2”之前计算所有唯一值。出现。例如,在上面,我希望在“W2”之前计算唯一值。为1,仅为最后一行,直至“W2”。第1行与第2行相同,第3行与第4行相同。

应该怎么做?

2 个答案:

答案 0 :(得分:3)

一种可行的方法是在W2之前提取零件:

# option 1:
vec <- substr(df$moves, 1, regexpr('W2\\.', df$moves) - 1)

# option 2:
vec <- sub('W2.*', '', df$moves)

然后看看它们是否是唯一的:

sum(!duplicated(vec) & !duplicated(vec, fromLast = TRUE))

给出:

> sum(!duplicated(vec) & !duplicated(vec, fromLast = TRUE))
[1] 1

这是做什么的:

  • regexpr('W2\\.', df$moves)提取W2首次出现的位置。
  • 从这些职位中提取1并将结果提供给substrsubstr(df$moves, 1, regexpr('W2\\.', df$moves) - 1)然后获取W2之前的部分。
  • 更简单的提取方法是使用sub而不是substr / regexpr - combo:sub('W2.*', '', df$moves)
  • !duplicated(vec) & !duplicated(vec, fromLast = TRUE)表示vec的哪些部分是唯一的。
  • 通过将其包装在sum中,您可以获得W2之前的唯一值数。

如果您想计算唯一值的数量而不是仅显示一次的值,您可以sum(!duplicated(vec)) length(unique(vec))

使用过的数据:

df <- structure(list(moves = c("W1.e4 B1.d5 W2.c4 B2.e6 W3.Nc3 B3.Nf6 W4.cxd5 B4.exd5 W5.Bg5", 
                               "W1.e4 B1.d5 W2.exd5 B2.Qxd5 W3.Nc3 B3.Qa5 W4.d4 B4.Nf6 W5.Nf3 B5.c6 W6.Ne5 B6.Bf5", 
                               "W1.e4 B1.e5 W2.Nf3 B2.Nc6 W3.Bc4", "W1.e4 B1.e5 W2.Nf3 B2.Nf6", "W1.e4 B1.c5 W2.Nf3")), 
                .Names = "moves", class = "data.frame", row.names = c(NA, -5L))

答案 1 :(得分:0)

使用strsplit预见 split参数split = " (?=W2\\.)"的选项可以是:

length(unique(sapply(strsplit(df$Moves, split = " (?=W2\\.)", perl = TRUE), 
                                                       function(x)x[1])))

#[1] 3

# where the unique values are:
unique(sapply(strsplit(df$Moves, split = " (?=W2\\.)", perl = TRUE),
                                                       function(x)x[1]))
#[1] "W1.e4 B1.d5" "W1.e4 B1.e5" "W1.e4 B1.c5"
  

<强>正则表达式:

" (?=W2\\.)"  -- space followed by W2.

数据:

df <- read.table(text = 
"Moves
'W1.e4 B1.d5 W2.c4 B2.e6 W3.Nc3 B3.Nf6 W4.cxd5 B4.exd5 W5.Bg5'
'W1.e4 B1.d5 W2.exd5 B2.Qxd5 W3.Nc3 B3.Qa5 W4.d4 B4.Nf6 W5.Nf3 B5.c6 W6.Ne5 B6.Bf5' 
'W1.e4 B1.e5 W2.Nf3 B2.Nc6 W3.Bc4'
'W1.e4 B1.e5 W2.Nf3 B2.Nf6'
'W1.e4 B1.c5 W2.Nf3'",
header = TRUE, stringsAsFactors = FALSE)