R 用条件表达式映射函数
背景:PDF解析我的程序在扫描的PDF文档中查找数据。我创建了一个CSV,其中的行表示要在PDF中搜索的各种参数,列表示可能包含这些参数的不同风格的文档。根据文档的类型,每个参数都有不同的标识符。列标题使用点分隔按类型、子类型…,唯一标识文档,类似于:R 用条件表达式映射函数,r,apply,R,Apply,背景:PDF解析我的程序在扫描的PDF文档中查找数据。我创建了一个CSV,其中的行表示要在PDF中搜索的各种参数,列表示可能包含这些参数的不同风格的文档。根据文档的类型,每个参数都有不同的标识符。列标题使用点分隔按类型、子类型…,唯一标识文档,类似于:type.subtype.s\u subtype.s\u subtype t.s.s2.s3 t.s.s2.s3 t.s.s2.s3 t.s.s2.s3 ... p1 str1 str2 p2
type.subtype.s\u subtype.s\u subtype
t.s.s2.s3 t.s.s2.s3 t.s.s2.s3 t.s.s2.s3 ...
p1 str1 str2
p2 str3 str4
p3 str5 str6
p4 str7
...
我正在阅读PDF文件,根据文件路径,它们可以被唯一地分类为以下类型之一。我可以对给定文件路径的子字符串应用各种逻辑条件,并在此基础上输出NxM
布尔矩阵,其中N=NROW(filepath\u vector)
,和M=ncol(params\u csv)
。此矩阵将显示给定文件在类型中的成员身份,在其他地方为TRUE
,而在类型中为FALSE
t.s.s2.s3 t.s.s2.s3 t.s.s2.s3 t.s.s2.s3 ...
fpath1 FALSE FALSE TRUE FALSE
fpath2 FALSE TRUE FALSE FALSE
fpath3 FALSE TRUE FALSE FALSE
fpath4 FALSE FALSE FALSE TRUE
...
我的解决方案:我试图将函数应用于以向量为参数的矩阵,并将向量的第一个元素应用于第一行,将第二个元素应用于第二行,等等。。。但是,函数具有条件行为,具体取决于所应用向量的元素
我知道这与下面的问题(我的参考点)非常相似,但是我函数中的条件让我很困惑。我在下面提供了一个简化的可复制的问题示例
但我得到了这个错误:
Error in if (y == 8) { : missing value where TRUE/FALSE needed
似乎无法找出错误,或者如果我在整个方法的其他地方被误导,任何想法都是值得赞赏的
更新(2018年4月3日):
# [,1] [,2] [,3] [,4] [,5]
# [1,] -1 0 -1 -1 -1
# [2,] 4 4 0 4 0
# [3,] 3 0 3 3 0
# [4,] 2 0 2 2 0
# [5,] 1 1 1 1 0
# $v1
# [1,] FALSE TRUE TRUE FALSE FALSE FALSE
# $v2
# [2,] FALSE FALSE FALSE FALSE FALSE FALSE
# $v3
# [3,] FALSE FALSE FALSE FALSE FALSE FALSE
为了再现性,我提供了一个玩具示例,但我认为在@grand_chat的优秀解决方案中使用类似于我的实际代码的东西会更有用。希望这有助于解决类似问题的人
chk <- c(NA, "abc.TRO", "def.TRO", "ghi.TRO", "kjl.TRO", "mno.TRO")
len <- c(8, NA, NA)
seed <- c(FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE)
A = matrix(seed, nrow=3, ncol=6, byrow=TRUE)
pairs <- mapply(list, as.data.frame(t(A)), len, SIMPLIFY=F)
f <- function(pair) {
x = unlist(pair[[1]])
y = pair[[2]]
if(y==8 & !is.na(y)) {
x[c(grep("TRO", chk))] <- (x[c(grep("TRO", chk))] & TRUE)
} else {x <- (x & FALSE)}
return(x)
}
t(mapply(f, pairs))
您正在并行处理vector
v
的元素和矩阵m
(数据帧的列t(m)
)的行,因此您可以将相应的元素压缩到成对列表中并处理成对。试试这个:
x <- y <- 5
m <- matrix(rbinom(x*y,1,0.5),x,y)
v <- c("321", "", "A160470", "7IDJOPLI", "ACEGIKM")
# Zip into pairs:
pairs <- mapply(list, as.data.frame(t(m)), v, SIMPLIFY=F)
# Define a function that acts on pairs:
f <- function(pair) {
x = pair[[1]]
y = pair[[2]]
if(nchar(y)==8) {x=x*2
} else if (nchar(y)==7) {
if(grepl("^[[:alpha:]]*$", substr(y, 1, 1))) {x=x*3}
else {x}
} else if (nchar(y)<3) {x=x*4
} else {x=x-2}
}
# Apply it:
mapply(f, pairs, SIMPLIFY=F)
(这与您期望的输出不一致,因为您似乎没有正确应用函数
f
。啊,很抱歉!刚刚编辑并更新了它。感谢您提供此解决方案!我试着将它应用到我的实际代码中,结果得到了奇怪的输出,我无法进行故障排除,所以我用它更新了我的问题-如果您有任何想法,我将非常感谢您的输入。我不确定接受你的解决方案是否能解决问题,这样人们就看不见了,所以我暂时暂缓,但我认为这是最好的方法。没关系,我已经解决了!更新了我的问题,以使用我的实际代码应用您的解决方案,以便于说明。
x <- y <- 5
m <- matrix(rbinom(x*y,1,0.5),x,y)
v <- c("321", "", "A160470", "7IDJOPLI", "ACEGIKM")
# Zip into pairs:
pairs <- mapply(list, as.data.frame(t(m)), v, SIMPLIFY=F)
# Define a function that acts on pairs:
f <- function(pair) {
x = pair[[1]]
y = pair[[2]]
if(nchar(y)==8) {x=x*2
} else if (nchar(y)==7) {
if(grepl("^[[:alpha:]]*$", substr(y, 1, 1))) {x=x*3}
else {x}
} else if (nchar(y)<3) {x=x*4
} else {x=x-2}
}
# Apply it:
mapply(f, pairs, SIMPLIFY=F)
$V1
[1] -2 -1 -2 -2 -1
$V2
[1] 4 4 0 0 4
$V3
[1] 3 3 3 3 0
$V4
[1] 2 0 2 2 0
$V5
[1] 0 0 3 0 3