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

R 在特定模式之前计算唯一值的数量?,r,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 我想

我在数据框中有一列
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行相同


如何实现这一点?

使用带有前瞻性
split
参数的
strsplit=“(?=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"
Regex:

" (?=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)

df使用
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"
Regex:

" (?=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)

df一种可能的方法是提取
W2
之前的零件:

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

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

它的作用是:

  • regexpr('W2\\.',df$moves)
    提取第一次出现
    W2
    的位置
  • 从这些位置减去
    1
    ,并将结果馈送到
    substr
    substr(df$moves,1,regexpr('W2\\.',df$moves)-1)
    然后获取
    W2
    之前的部分
  • 一种更简单的提取方法是使用
    sub
    而不是
    substr
    /
    regexpr
    -组合:
    sub('W2.*','',df$moves)
  • !重复(vec)&!重复(vec,fromLast=TRUE)
    表示vec的哪些部分是唯一的
  • 通过将其包装在
    sum
    中,可以得到
    W2
    之前的唯一值的数量

如果要计算唯一值的数量,而不是只出现一次的值,可以执行
sum(!duplicated(vec))
of
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))

df一种可能的方法是提取
W2
之前的零件:

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

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

它的作用是:

  • regexpr('W2\\.',df$moves)
    提取第一次出现
    W2
    的位置
  • 从这些位置减去
    1
    ,并将结果馈送到
    substr
    substr(df$moves,1,regexpr('W2\\.',df$moves)-1)
    然后获取
    W2
    之前的部分
  • 一种更简单的提取方法是使用
    sub
    而不是
    substr
    /
    regexpr
    -组合:
    sub('W2.*','',df$moves)
  • !重复(vec)&!重复(vec,fromLast=TRUE)
    表示vec的哪些部分是唯一的
  • 通过将其包装在
    sum
    中,可以得到
    W2
    之前的唯一值的数量

如果要计算唯一值的数量,而不是只出现一次的值,可以执行
sum(!duplicated(vec))
of
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))

每行的df值是多少?每一列?有点不清楚。输出应该是什么样子?对于列(
df$moves
是一列)。输出应该只是一个数字,在某个字符串之前唯一值的计数by unique您的意思是只显示一次的值?根据您的描述,看起来您正在查找只出现一次的值。在我们的示例数据中,计算唯一值会导致
3
。对于每一行?每一列?有点不清楚。输出应该是什么样子?对于列(
df$moves
是一列)。输出应该只是一个数字,在某个字符串之前唯一值的计数by unique您的意思是只显示一次的值?根据您的描述,看起来您正在查找只出现一次的值。在我们的示例数据中,计算唯一值的结果是
3
。您正在计算每行中
W2
的接近次数,而OP希望“在字符“W2.”出现之前具有唯一值”@Jaap您是正确的。也许,预期的产出并不是很清楚,但附加的评论已经澄清了这一点。你的回答是最合适的,让我看看是否能找到替代方案☺. 否则我将删除我的。您正在计算每行中
W2
的接近次数,而OP希望在字符“W2”出现之前有“唯一值”。@Jaap您是正确的。也许,预期的产出并不是很清楚,但附加的评论已经澄清了这一点。你的回答是最合适的,让我看看是否能找到替代方案☺. 否则我会删除我的。