测试多列中的多个字符串

时间:2014-10-10 11:46:47

标签: r

我在堆栈溢出上进行了大量搜索,但没有找到以下问题的答案: 我正在寻找一个函数,让我测试一些列是否包含任何指定的字符串。

# I'm looking for heart attacks
infarction <- c("b", "c")
# I'm also looking for strokes
stroke <- c("h", "i")

#sample data set
set.seed(1234)
dat <- data.frame(A = sample(letters[1:9],10,TRUE),
                  B = sample(letters[1:9],10,TRUE),
                  C = sample(letters[1:9],10,TRUE),
                  D = sample(letters[1:9],10,TRUE),
                  DATE = sample.int(10, size = 10, replace = FALSE))

# I've tried many things. Among them:
# first one using the dplyr package.

infarction = ifelse( (infarction  %in% dat[,c("A", "B", "C", "D")]), DATE, NA))

#excluded a few rows from the mutate...

#I've also tried
grep(paste(infarction,collapse="|"), dat[,1:4], value=TRUE), DATE, NA))

总结一下。如果我只检查一列或只查看其中一个字符串,我可以让它工作。但是我需要检查任何给定列中是否包含任何字符串,在这种情况下,将日期值作为新变量返回。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

如果您只想知道列是否包含字母,可以应用data.frame %in%函数的每一列:

apply(dat[,-5], 2, '%in%', x=stroke)

如果您想知道列中stroke的每个字母的位置,可以使用which函数将其应用于每列:

apply(dat[,-5], 2, function(table,x) which(x==table), x=stroke[1])
apply(dat[,-5], 2, function(table,x) which(x==table), x=stroke[2])

sapply(stroke, function(y) apply(dat, 2, function(table,x) which(x==table), x=y), simplify=FALSE)

如果您想知道所有笔画字母的位置,请执行以下操作:

apply(dat[,-5], 2, function(x) unlist(sapply(stroke , function(i) which( i == x))))

答案 1 :(得分:2)

这取决于您想要的输出。 @Pop的回答非常好我只想补充说你的grep方法在正确的轨道上,除非你不能在x参数中给它一个数据框。你必须按列执行它。这是因为grep会将x参数强制转换为某个字符,您可以看到键入as.character(dat[, 1:4])是否grep错误的字符串。相反,尝试例如

grepres <- lapply(dat[1:4], grep, pattern = paste(infarction,collapse="|"))

如果要查找哪些行不包含您可以执行的模式,例如

idx <- setdiff(1:nrow(dat), unlist(grepres))

然后

result <- rep(NA, nrow(dat))
result[idx] <- dat$DATE[idx]

答案 2 :(得分:1)

以下可能会有所帮助:

> apply(dat, 1, function(x) ifelse(infarction %in% x[1:5],x[5],NA  ))
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] " 6" NA   " 3" NA   " 2" NA   " 7" NA   " 1" NA   
[2,] " 6" "10" " 3" NA   " 2" NA   " 7" " 9" NA   " 4" 

以data.frame形式:

> as.data.frame(t(apply(dat, 1, function(x) ifelse(infarction %in% x[1:5],x[5],NA  ))))

     V1   V2
1     6    6
2  <NA>   10
3     3    3
4  <NA> <NA>
5     2    2
6  <NA> <NA>
7     7    7
8  <NA>    9
9     1 <NA>
10 <NA>    4

中风:

> as.data.frame(t(apply(dat, 1, function(x) ifelse(stroke %in% x[1:5],x[5],NA  ))))

     V1   V2
1  <NA> <NA>
2  <NA> <NA>
3  <NA> <NA>
4  <NA>    5
5     2 <NA>
6     8 <NA>
7  <NA> <NA>
8  <NA>    9
9     1    1
10    4 <NA>