Как оптимизировать эти циклы в R

Я нахожусь в процессе очистки данных и в конечном итоге с большим количеством for петель. Поскольку у моего набора данных больше 6 миллионов строк, для меня это проблема, но я не уверен, как этого избежать.

Примером моего набора данных (называемого sentencing.df) было бы что-то вроде:

Ethnicity PersonNumber

 Caucasian 1
 Caucasian 1
 Unknown 1
 Indian 2
 Indian 2

Я хочу сравнить с одним и тем же номером человека - например, я хочу знать, одинаковы ли этнические группы для каждого человека (а затем изменить неправильные записи, если они существуют). Мой код использует для циклов и выглядит примерно так:

PersonListRace <- unique(sentencing.df[sentencing.df$ethnicity == "UNKNOWN",]$PersonNumber) 
PersonListRace <- as.numeric(as.character(PersonListRace))
 # vector of person numbers for those with ethnicity UNKNOWN

for (i in 1:100) {
 race <- sentencing.df[sentencing.df$PersonNumber == PersonListRace[i],]$ethnicity
 # creates a vector of unique ethnicities for that person
 if (length(unique(race)) != 2) {next}
 # excludes those who only have UNKNOWN or who have UNKNOWN plus multiple ethnicities
 else {
 label <- as.character(unique(race[which(race != "UNKNOWN")]))
 sentencing.df[sentencing.df$PersonNumber == PersonListRace[i],]$ethnicity <- label
 }
}

Затем у меня есть похожие вещи для всех моих других переменных, а циклы for занимают слишком много времени для запуска. Я рассмотрел некоторые другие вопросы и ответы на сайте, но моя основная проблема заключается в том, что я не могу найти способ сравнения только внутри одного и того же номера человека по другой переменной без использования цикла for.

Все, что помогло бы мне достичь моей цели в практические сроки, было бы очень оценено :)

1 ответ

Ни одна из моих проблем не была затронута в комментарии, поэтому я просто возьму пример как полностью отражающий сложность проблемы (хотя мой опыт в том, что вещи редко бывают настолько простыми);

dat <- read.table(text="Ethnicity PersonNumber
 Caucasian 1
 Caucasian 1
 Unknown 1
 Indian 2
 Indian 2", header=TRUE)
 dat$TrueEth <- with( dat, ave(Ethnicity, PersonNumber, 
 FUN=function(perE){
 unique( perE[perE != "Unknown"] ) } ) )

> dat
 Ethnicity PersonNumber TrueEth
1 Caucasian 1 Caucasian
2 Caucasian 1 Caucasian
3 Unknown 1 Caucasian
4 Indian 2 Indian
5 Indian 2 Indian

Выдающиеся проблемы - это то, что нужно делать с более чем одной ценностью для этнической принадлежности, и если ответ - это правила большинства, что делать, если есть равное количество не-Неизвестных.

licensed under cc by-sa 3.0 with attribution.