2016-01-17 46 views
3

我想爲一個數據幀的每一行計算一個字符串中定義的模式(這裏:'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) 

在此先感謝!

+1

我相信'str_'函數應該都是矢量化的。不需要「喂」它們。此外,'gregexpr(「Y」,df $ V2)'應該基本上給這個基地R. – thelatemail

+0

謝謝,但你的解決方案給出'Y'的位置,而不是發生次數和/或長度 – user2904120

+1

@thelatemail如果更改模式設置爲「Y +」,則匹配長度將被正確捕獲。 – steveb

回答

1

這裏是一個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 = ",") 
    }) 
+0

如何指定隨機字符,例如Y * Y,所以搜索出現XYYXYX,其中包含YXY – user2904120

1

在基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 = ",")) 
+0

任何想法如何將其作爲一個函數運行,因此可以簡單地指定一個模式,例如「Y」,「YY」還是「X」? – user2904120

+0

@ user2904120看到我的答案在下面的函數 –

2

另一個基礎R溶液,但使用regexpr

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

提取match.lengthregexpr輸出的屬性,然後計算每個a的長度ttribute(這告訴你有多少場比賽有):

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 <- 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+')

相關問題