【问题标题】:Count patterns and differentiate them计算模式并区分它们
【发布时间】:2016-01-17 23:20:09
【问题描述】:

我想为数据帧的每一行计算一个字符串中定义的模式(这里:'Y')。理想情况下,我希望在 V3 中出现多次,在 V4 中获得长度。

输入:

V1  V2
A   XXYYYYY
B   XXYYXX
C   XYXXYX
D   XYYXYX

输出:

V1       V2 V3   V4
 A  XXYYYYY  1    5
 B   XXYYXX  1    2
 C   XYXXYX  2  1,1
 D   XYYXYX  2  2,1

我尝试了以下函数的不同修改,但没有成功。

dict <- setNames(nm=c("Y"))
seqs <- df$V2
sapply(dict, str_count, string=seqs)

提前致谢!

【问题讨论】:

  • 我相信str_ 函数都应该被矢量化。无需sapply 他们。此外,gregexpr("Y", df$V2) 本质上应该在基础 R 中给出这个。
  • 谢谢,但您的解决方案给出了“Y”的位置,而不是出现次数和/或长度
  • @thelatemail 如果您将模式更改为"Y+",匹配长度将被正确捕获。
  • @steveb - 是的,我忘记了+。
  • @user2904120 输出“D”的最后一行缺少“Y”(参见输入)。

标签: r count stringr find-occurrences


【解决方案1】:

另一个基本 R 解决方案,但使用 regexpr:

df <- data.frame(
  V1 = c("A", "B", "C", "D"),
  V2 = c("XXYYYYY", "XXYYXX" , "XYXXYX", "XYYXYX")
)

提取regexpr 输出的match.length 属性,然后计算每个属性的长度(告诉您有多少匹配项):

r <- gregexpr("Y+", df$V2)
len <- lapply(r, FUN = function(x) as.array((attributes(x)[[1]])))
df$V3 <- lengths(len)
df$V4 <- len

df
#V1      V2 V3   V4
#1  A XXYYYYY  1    5
#2  B  XXYYXX  1    2
#3  C  XYXXYX  2 1, 1
#4  D  XYYXYX  2 2, 1

如果你有一个旧版本的 R 没有 lengths,但你可以使用 df$V3 &lt;- sapply(len, length) 代替。 如果您需要更通用的函数来对任何向量 x 和模式 a 执行相同操作:

foo <- function(x, a){
  ans <- data.frame(x)
  r <- gregexpr(a, x)
  len <- lapply(r, FUN = function(z) as.array((attributes(z)[[1]])))
  ans$quantity <- lengths(len)
  ans$lengths <- len
  ans
}

试试foo(df$V2, 'Y+')。

【讨论】:

    【解决方案2】:

    这是stringr 解决方案:

    df <- data.frame(
      V1 = c("A", "B", "C", "D"),
      V2 = c("XXYYYYY", "XXYYXX" , "XYXXYX", "XYYXYX")
      )
    
    df$V3 <- str_count(df$V2, "Y+")
    
    df$V4 <- lapply(str_locate_all(df$V2, "Y+"), function(x) {
        paste(x[, 2] - x[, 1] + 1, collapse = ",")
      })
    

    【讨论】:

    • in df$V3
    【解决方案3】:

    在基础 R 中:

    aaa <- data.frame(V1 = LETTERS[1:4], 
                      V2 = c("XXYYYYY", "XXYYXX", "XYXXYX", "XYYXYX"),
                      stringsAsFactors = FALSE)
    
    # split into strings of "Y"s
    splt <- lapply(aaa$V2, function(x) unlist(strsplit(x, "[^Y]+"))[-1])
    
    # number of occurrences
    aaa$V3 <- lapply(splt, length)
    
    # length of each occurence
    aaa$V4 <- lapply(splt, function(x) paste(nchar(x), collapse = ","))
    

    【讨论】:

    • 任何想法如何将其作为一个函数运行,因此可以简单地指定一种模式,例如“Y”、“YY”还是“X”?
    • @user2904120 请参阅下面的函数答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多