R Подсчитать количество строк в векторе по столбцам в кадре данных - PullRequest
0 голосов
/ 29 ноября 2018

У меня большой фрейм данных (3 миллиона уникальных строк 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, после того как функция нашла все три строки в этой строке вектора.Однако, выполнение этого с 3 миллионами итераций по вектору 200k слишком медленное.Есть идеи?

Ответы [ 3 ]

0 голосов
/ 29 ноября 2018
# 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)
0 голосов
/ 30 ноября 2018

Вот базовый однострочный R, использующий strsplit и %in%:

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

Это также учитывает дополнительные поля в y.Пока все записи в x присутствуют в y, количество увеличивается.

0 голосов
/ 29 ноября 2018

Вы можете использовать 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())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...