[英]R: Recursive *ply/plyr function; for loop replacement
我正在嘗試用* ply類型的函數替換for循環。
我遇到的問題是我不確定如何重復更新相同的數據。
這是一些示例數據(我知道可以通過其他方法完成此特定示例,但這只是為了簡單起見-我的實際示例要復雜得多):
sample_pat_rep <- data.frame(matrix(NA, ncol=2, nrow=3, dimnames=list(c(), c("Pattern","Replacement"))), stringsAsFactors=FALSE)
sample_pat_rep[1,] <- c("a","A")
sample_pat_rep[2,] <- c("b","B")
sample_pat_rep[3,] <- c("c","C")
sample_strings <- data.frame(matrix(NA, ncol=2, nrow=3, dimnames=list(c(), c("Original","Fixed"))), stringsAsFactors=FALSE)
sample_strings[1,] <- c("aaaaaaaa bbbbbbbb cccccccc","aaaaaaaa bbbbbbbb cccccccc")
sample_strings[2,] <- c("aAaAaAaA bBbBbBbB cCcCcCcC","aAaAaAaA bBbBbBbB cCcCcCcC")
sample_strings[3,] <- c("AaAaAaAa BbBbBbBb CcCcCcCc","AaAaAaAa BbBbBbBb CcCcCcCc")
這是一個for循環版本:
sample_strings1 <- sample_strings
for (i in 1:nrow(sample_pat_rep))
{
sample_strings1[,c("Fixed")] <- gsub(sample_pat_rep[i,c("Pattern")], sample_pat_rep[i,c("Replacement")], sample_strings1[,c("Fixed")],ignore.case = TRUE)
}
當我嘗試用adply復制它時,它不會更新數據-它必不可少地復制和綁定數據。
sample_strings2 <- adply(.data=sample_pat_rep, .margins=1, .fun = function(x,data){
data[,c("Fixed")] <- gsub(x[,c("Pattern")], x[,c("Replacement")], data[,c("Fixed")],ignore.case = TRUE)
return(data)
}, data=sample_strings, .expand = FALSE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL)
我敢肯定有一個簡單的解決方法。 我看了看拉普利(Rapply),但不清楚是否可以解決問題。
也許寫一個函數來進行調用?? 使用Rapply?
提前謝謝!
更新:新數據
這更接近實際情況。 匹配是動態的,基於外部系統。 我試圖避免過於復雜的正則表達式或嵌套其他情況。
library(plyr)
sample_match <- data.frame(matrix(NA, ncol=1, nrow=3, dimnames=list(c(), c("Match"))), stringsAsFactors=FALSE)
sample_match[1,] <- c("dog")
sample_match[2,] <- c("cat")
sample_match[3,] <- c("bear")
sample_strings <- data.frame(matrix(NA, ncol=2, nrow=3, dimnames=list(c(), c("Sentence","Has_Animal"))), stringsAsFactors=FALSE)
sample_strings[1,] <- c("This person only has a cat",0)
sample_strings[2,] <- c("This person has a cat and a dog",0)
sample_strings[3,] <- c("This person has no animals",0)
sample_strings1 <- sample_strings
for (i in 1:nrow(sample_match))
{
sample_strings1[,c("Has_Animal")] <- ifelse(grepl(sample_match[i,c("Match")], sample_strings1[,c("Sentence")]), 1,sample_strings1[,c("Has_Animal")])
}
sample_strings2 <- adply(.data=sample_match, .margins=1, .fun = function(x,data){
data[,c("Has_Animal")] <- ifelse(grepl(x[,c("Match")], data[,c("Sentence")]), 1,data[,c("Has_Animal")])
return(data)
}, data=sample_strings, .expand = FALSE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL)
更新:誤解了這個問題,即sample_strings2
是必需的結果。 現在更新了給出sample_strings1
的答案,即需要IIUC。
這是使用base
的解決方案:
pattern = paste(sample_match$Match, collapse="|")
transform(sample_strings, Has_Animal = grepl(pattern, Sentence)*1L)
# Sentence Has_Animal
# 1 This person only has a cat 1
# 2 This person has a cat and a dog 1
# 3 This person has no animals 0
如果您不希望匹配包含模式的單詞,例如: concatenate
contains cat
,則可以將正則表達式\\b
用於單詞邊界。
pattern = paste(paste("\\b", sample_match$Match, "\\b", sep=""), collapse="|")
grepl(pattern, c("cat", "concatenate"))
# [1] TRUE FALSE
這里是一個直plyr
方法的問題:
ddply(sample_strings,.(Sentence),function(x,ref = sample_match) {
any(unlist(strsplit(x[["Sentence"]]," ")) %in% ref[[1]])
})
Sentence V1
1 This person has a cat and a dog TRUE
2 This person has no animals FALSE
3 This person only has a cat TRUE
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.