Я довольно новичок в R, и у меня возникает следующая проблема.
У меня есть такой фрейм данных:
A | B | C | E | F |G
1 02 XXX XXX XXX 1
1 02 XXX XXX XXX 1
2 02 XXX XXX XXX NA
2 02 XXX XXX XXX NA
3 02 XXX XXX XXX 1
3 Z1 XXX XXX XXX 1
4 02 XXX XXX XXX 2
....
M 02 XXX XXX XXX 1
Дело в том, что фрейм данных может содержать 150 тыс. Строк илибольше, и мне нужно сгенерировать другую группировку данных по A
(которая является идентификатором) и подсчитать следующие вхождения:
Когда B равно 02 и G имеет 1 <- V <br>Когда B равно 02и G представляет собой NA <- W <br>Когда B представляет собой Z1 и G имеет 1 <- X <br>Когда B представляет собой Z1 и G представляет собой NA <- Y <br>Любой другой вид вхождения <- Z <br>
В этом простом примере результат должен выглядеть примерно так:
A | V | W | X | Y | Z
1 2 0 0 0 0
2 0 2 0 0 0
3 1 1 0 0 0
4 0 0 0 0 1
...
M 1 0 0 0 0
На данный момент мне удалось получить результаты с помощью цикла for:
get_counters <- function(df){
counters <- data.frame(matrix(ncol = 6, nrow = length(unique(df$A))))
colnames(counters) <- c("A", "V", "W", "X", "Y", "Z")
counters$A<- unique(df$A)
for (i in 1:nrow(counters)) {
counters$V[i] <- sum(df$A == counters$A[i] & df$B == "02" & df$G == 1, na.rm = TRUE)
counters$W[i] <- sum(df$A == counters$A[i] & df$B == "02" & is.na(df$G), na.rm = TRUE)
counters$X[i] <- sum(df$A == counters$A[i] & df$B == "Z1" & df$G== 1, na.rm = TRUE)
counters$Y[i] <- sum(df$A == counters$A[i] & df$B == "Z1" & is.na(df$G), na.rm = TRUE)
counters$Z[i] <- sum(df$A == counters$A[i] & (df$B == "Z1" | df$B == "02") & df$G!= 1, na.rm = TRUE)
}
return(counters)
}
Попыткачто на небольшом тесте датафрейм возвращает все правильные результаты, но с реальными данными это крайне медленно.Я не уверен, как использовать функции apply
, кажется простой проблемой, но я не нашел ответа.До сих пор я предполагал, что если бы я мог использовать apply
с оператором sum
в моем цикле for (возможно, используя group_by(A)
), я мог бы это сделать, но я получаю все виды ошибок.
counters$V <- df%>%
group_by(A)%>%
sum(df$A == counters$A& df$B == "02" &df$G == 1, na.rm = TRUE)
Error in FUN(X[[i]], ...) :
only defined on a data frame with all numeric variables
In addition: Warning message:
In df$A== counters$A:
longer object length is not a multiple of shorter object length
Если я изменю функцию, чтобы не использовать цикл for и не использовал $
(я получаю сообщение об ошибке "$ operator is invalid for atomic vectors"
), я либо получаю больше ошибок, либо странные нечитаемые результаты (Большие списки, которые содержат больше значений, чем исходный фрейм данных, огромные пустые матрицы и т. Д.)
Существует ли простой (возможно, не простой, но быстрый и эффективный) способ решения этой проблемы?Заранее спасибо.