Как мне установить два условия, которые сами содержат более одного значения

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

В первом фрейме данных показаны все животные и их вес, принадлежащий группе фермеров, во втором фрейме данных указано, что на самом деле фермер продал всех животных определенного типа, поэтому их следует удалить из набора. В моем примере Джеймс продал всех своих оленей, а Алиса продала всех своих цыплят Гига, но Шуберт не продал своих оленей, поэтому с ним ничего не нужно делать. Если бы была только одна переменная, я мог бы использовать% в%, но я не смог бы заставить это работать с двумя переменными. Я решил это с помощью грязных вложенных циклов if и for, но я думаю, что есть гораздо более эффективный метод.

owner <-c("Fred", "Mary", "James", "Ingrid", "Schubert", "Alice") #owner names
animal <-c("Cow", "Giant sheep", "Deer", "Giga chicken") #Animal types
data <- data.frame(owner= sample(owner, 1000, replace= TRUE), animal=sample(animal, 1000, replace= TRUE), weight=rnorm(1000,mean=250, sd=50)) #data set

sub.set <- data.frame(cbind(c("James","Alice", "Schubert"),c("Deer","Giga chicken", "Deer"), c(0,0,1)))

for (i in unique(sub.set[,1])) {
    for (y in unique(sub.set[,2])) {

        #first if statement prevents error that occur if the subset data doesn't have one of the loop combinations
        if(length(sub.set[sub.set$X1 ==i & sub.set$X2 ==y,3])>0){
            if (sub.set[sub.set$X1 ==i & sub.set$X2 ==y,3]==0)
            { data <- data[!(data$owner==i & data$animal==y),]}
        }
    }
}
xtabs(weight ~., data)

Как видно из кросс-таблицы, правильные элементы были выделены, но ужасным образом помощь в выполнении этой операции была бы очень признательна!

1 ответ

Решение

Это дает идентичный результат вашему коду и не использует циклы.

set.seed(1)   # need reproducible sample data
owner <-c("Fred", "Mary", "James", "Ingrid", "Schubert", "Alice") #owner names
animal <-c("Cow", "Giant sheep", "Deer", "Giga chicken") #Animal types
data <- data.frame(owner= sample(owner, 1000, replace= TRUE), 
                   animal=sample(animal, 1000, replace= TRUE), 
                   weight=rnorm(1000,mean=250, sd=50)) #data set
# note the column names in sub.set
sub.set <- data.frame(owner=c("James","Alice", "Schubert"),
                      animal=c("Deer","Giga chicken", "Deer"), 
                      count=c(0,0,1))
# this is the code to exclude rows where there are no animals left
data <- merge(data,sub.set,by=c("owner","animal"),all.x=T)
data <- with(data,data[count!=0 | is.na(count),])
data <- data[,-4]
xtab.2 <- xtabs(weight~.,data)

Этот код сливается data а также sub.set на колоннах owner а также animal создать новый столбец count, Тогда он включает в себя только строки, где count!=0 или же !is.na(count), Затем он удаляет count столбец и вычисляет кросс-таблицу, как и раньше.

Другие вопросы по тегам