2013-03-24 27 views
5

确定字串的频率,如果我有一个载体用grep

x <- c("ajjss","acdjfkj","auyjyjjksjj") 

做:

y <- x[grep("jj",x)] 
table(y) 

我得到:

y 
     ajjss auyjyjjksjj 
      1   1 

但是第二串 “auyjyjjksjj” 应该算子串“jj”两次。我怎样才能从真/假计算中改变这种情况,到实际计算“jj”的频率?

此外,如果对于每个字符串,子字符串的频率除以字符串的长度可以计算出来,这将是很大的。

在此先感谢。

回答

8

我解决了这个使用gregexpr()

x <- c("ajjss","acdjfkj","auyjyjjksjj") 
freq <- sapply(gregexpr("jj",x),function(x)if(x[[1]]!=-1) length(x) else 0) 
df<-data.frame(x,freq) 

df 
#   x freq 
#1  ajjss 1 
#2  acdjfkj 0 
#3 auyjyjjksjj 2 

而对于最后一部分的问题,计算频率/字符串长度 ...

df$rate <- df$freq/nchar(as.character(df$x)) 

的是nece ssary将df $ x转换回字符串,因为除非指定stringsAsFactors = F,否则data.frame(x,freq)会自动将字符串转换为因子。

df 
#   x freq  rate 
#1  ajjss 1 0.2000000 
#2  acdjfkj 0 0.0000000 
#3 auyjyjjksjj 2 0.1818182 
+0

这是非常好的谢谢。我注意到你计算字符串的长度 - 在data.frame中我可以调用频率/长度吗?这将是非常有用的。谢谢。 – brucezepplin 2013-03-24 16:22:23

+0

对不起 - 我的意思是,我可以为每个字符串返回子字符串的频率除以字符串的长度吗? – brucezepplin 2013-03-24 16:26:05

+0

抱歉 - 我; m在nchar(df $ x)中获取错误:'nchar()'需要一个字符向量 – brucezepplin 2013-03-24 16:32:12

7

您正在使用错误的工具。尝试gregexpr,这将给你在搜索字符串被发现的位置(或-1,如果没有找到):

> gregexpr("jj", x, fixed = TRUE) 
[[1]] 
[1] 2 
attr(,"match.length") 
[1] 2 
attr(,"useBytes") 
[1] TRUE 

[[2]] 
[1] -1 
attr(,"match.length") 
[1] -1 
attr(,"useBytes") 
[1] TRUE 

[[3]] 
[1] 6 10 
attr(,"match.length") 
[1] 2 2 
attr(,"useBytes") 
[1] TRUE 
+0

非常感谢,这是非常有益的。 – brucezepplin 2013-03-24 16:24:24

+0

现在我认为这个位置对我来说实际上非常有用。谢谢。 – brucezepplin 2013-03-24 16:31:07

3

您可以使用qdap(虽然不是在基地安装R):

x <- c("ajjss","acdjfkj","auyjyjjksjj") 
library(qdap) 
termco(x, seq_along(x), "jj") 

## > termco(x, seq_along(x), "jj") 
## x word.count   jj 
## 1 1   1 1(100.00%) 
## 2 2   1   0 
## 3 3   1 2(200.00%) 

注意,输出具有频率和频率比较字数(输出实际上是一个列表,但打印漂亮输出)。要访问频率:

termco(x, seq_along(x), "jj")$raw 

## > termco(x, seq_along(x), "jj")$raw 
## x word.count jj 
## 1 1   1 1 
## 2 2   1 0 
## 3 3   1 2 
2

这简单的一行在base r利用strsplit,然后grepl,而且是相当强劲,但将打破,如果有计数的比赛就像jjjjjj为3手的jj。使这成为可能的模式匹配是从@JoshOBriens excellent Q&A

sum(grepl("jj" , unlist(strsplit(x , "(?<=.)(?=jj)" , perl = TRUE)))) 



# Examples.... 
f<- function(x){ 
    sum(grepl("jj" , unlist(strsplit(x , "(?<=.)(?=jj)" , perl = TRUE)))) 
    } 

    #3 matches here 
    xOP <- c("ajjss","acdjfkj","auyjyjjksjj") 
    f(xOP) 
    # [1] 3 

    #4 here 
    x1 <- c("ajjss","acdjfkj", "jj" , "auyjyjjksjj") 
    f(x1) 
    # [1] 4 

    #8 here 
    x2 <- c("jjbjj" , "ajjss","acdjfkj", "jj" , "auyjyjjksjj" , "jjbjj") 
    f(x2) 
    # [1] 8 

    #Doesn't work yet with multiple jjjj matches. We want this to also be 8 
    x3 <- c("jjjj" , "ajjss","acdjfkj", "jj" , "auyjyjjksjj" , "jjbjj") 
    f(x3) 
    # [1] 7 
+0

这确实提出了一个重要的观点 - 接受的答案已经解决了这个问题。如果我有“jjjjjj”,我想返回3的频率。但是,如果我允许频率计数的重叠使得频率为5,那么这将是一个问题。谢天谢地,情况并非如此!但谢谢你指出这一点。 – brucezepplin 2013-03-24 19:57:50