R像向量中的行一样按数据帧中的列计数

时间:2018-11-29 01:18:31

标签: r

我有一个大的数据框(300万个唯一行x 3列)。我需要计算数据帧的每次迭代,其中所有三列都一起出现在一个向量中(20000行)。向量是许多不同变量的串联。我有一个解决方案,但是需要几个小时才能运行。寻找建议以加快流程。示例:

X1 = c("AAA","ABC","DFD")
X2 = c("123","231","432")
X3 = c("12A","4GJ","213")
x <- data.frame(X1,X2, X3)
y <- c("ABD - 122 - XYZ", "ABC - 231 - 4GJ", "FDD - 213 - FJ2 - djf", "372 - DHFN - SJSN - fjd")

library(data.table)

### My Current Solution

freq <- rep(NA, nrow(x))
for (i in 1:nrow(x)) {
freq[i] <- length(which(y %like% x[i,1] & y %like% x[i,2] & y %like% x[i,3]))
}

### Solution 2
myfunc <- function(x) {freq <- length(which(y %like% x[1] & y %like% x[2] & y %like% x[3]))}

freq <- apply(x[,c(1:3)], 1, myfunc)

### Returns following Vector for both solutions
> freq
[1] 0 1 0

运行此命令会返回一个向量“ freq”,其中第一行包含1个在函数的该行中的所有三行之后都包含1的行。但是,在200k的向量上进行3百万次迭代来运行它太慢了。有任何想法吗?

3 个答案:

答案 0 :(得分:0)

您可以使用filter软件包中的dplyr

library(dplyr)

X1 = c("AAA","ABC","DFD")
X2 = c("123","231","432") 
X3 = c("12A","4GJ","213")

y <- data.frame(code = c("ABD - 122 - XYZ", "ABC - 231 - 4GJ - fjd", "FDD - 213 - FJ2", "372 - DHFN - SJSN"))


y %>% 
  filter(grepl(paste(X1, collapse="|"), code)) %>% 
  filter(grepl(paste(X2, collapse="|"), code)) %>% 
  filter(grepl(paste(X3, collapse="|"), code)) %>% 
  summarise(n = n())

答案 1 :(得分:0)

# Your Patterns
X1 = c("AAA","ABC","DFD")
X2 = c("123","231","432")
X3 = c("12A","4GJ","213")
x <- data.frame(X1,X2, X3)
x$pattern <- paste(x$X1, x$X2, x$X3, sep=" - ")

#put all your strings into one string
i <- 20000
string <- c("ABD - 122 - XYZ", 
        "ABC - 231 - 4GJ - fjd", "fjd - ABC - 231 - 4GJ", 
        "FDD - 213 - FJ2", "AAA - 123 - 12A - A", "AAA - 123 - 12A - B", 
        "AAA - 123 - 12A - c", 
        "372 - DHFN - SJSN", paste0(LETTERS[runif(i, 1,26)], LETTERS[runif(i,   1,26)])
        )

string2 <- paste0(string, collapse = ",")

#function to check each pattern against the string
cnt <- Vectorize(function(x){
      length(grepRaw(x, string2, all =T, fixed = T))
      }, SIMPLIFY = T)


#the result
cnt(x$pattern)

答案 2 :(得分:0)

以下是使用strsplit%in%的基本R单线:

freq <- apply(x, 1, function(x) sum(sapply(strsplit(y, " - "), function(y) all(x %in% y))))
freq
#[1] 0 1 0

这还将处理y中的其他字段。只要x中的所有条目都出现在y中,计数就会增加。