使用条件表达式

时间:2018-03-29 20:42:29

标签: r apply

背景:PDF解析我的程序在扫描的PDF文档中查找数据。我创建了一个CSV,其中的行表示要在PDF中搜索的各种参数,以及用于包含这些参数的不同文档类型的列。每个参数都有不同的标识符,具体取决于文档类型。列标题使用点分隔来按类型,子类型...唯一标识文档,如下所示:type.subtype.s_subtype.s_s_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_vector)M = ncol(params_csv)。此矩阵将在TRUEFALSE的其他类型的类型中显示给定文件的成员资格。

        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
...

我的解决方案:我正在尝试将函数应用于以向量作为参数的矩阵,并将向量的第一个元素应用于第一行,第二个元素应用于第二行行等等...但是,该函数具有条件行为,具体取决于所应用的向量的元素。

我知道这与下面的问题(我的参考点)非常相似,但我的功能中的条件让我感到沮丧。我在下面提供了一个简单的可重现的问题示例。

R: Apply function to matrix with elements of vector as argument

set.seed(300)

x <- y <- 5
m <- matrix(rbinom(x*y,1,0.5),x,y)

v <- c("321", "", "A160470", "7IDJOPLI", "ACEGIKM")

f <- function(x) {
  sapply(v, g <- function(y) {
    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}
  })
}

mapply(f, as.data.frame(t(m)))

期望的输出:

 #       [,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

但是我收到了这个错误:

 Error in if (y == 8) { : missing value where TRUE/FALSE needed

似乎无法弄清楚错误,或者如果我在我的整个方法中被误导,任何想法都会受到赞赏。

更新(03年3月3日):

为了重现性,我提供了这个作为玩具示例,但我认为使用@ 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))

输出:

# $v1       
# [1,]    FALSE   TRUE    TRUE    FALSE   FALSE   FALSE
# $v2
# [2,]    FALSE   FALSE   FALSE   FALSE   FALSE   FALSE
# $v3
# [3,]    FALSE   FALSE   FALSE   FALSE   FALSE   FALSE

1 个答案:

答案 0 :(得分:1)

您正在并行处理向量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)

结果:

$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

(这与您想要的输出不一致,因为您似乎没有正确应用您的函数f。)