сравнивая две переменные в одном столбце в R - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть две колонки.одна имеет список переменных, например, «кошка», «собака», «крыса», «курица», а другая - посещение зоомагазина во время первой или второй поездки.

visit_number    pet
      1         dog
      2         dog
      1         cat
      2         cat
      1         rat
      2         chicken

Я хочу сравнить разницу между двумя визитами в R, например, intersect() и setdiff().В основном точно так же, как этот вопрос:

Сравните два списка в R

Однако у меня нет двух списков, но есть две переменные в одном столбце, и яне могу заставить код работать.

я пытаюсь добиться такой функции, которая использует один столбец, а не два списка (код взят из другого вопроса):

xtab_set <- function(A,B){
    both    <-  union(A,B)
    inA     <-  both %in% A
    inB     <-  both %in% B
    return(table(inA,inB))
}

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Честно говоря, матрица вывода не очень понятна.Тем не менее, в комментарии вы упомянули, что «вы ищете количество (количество) уникальных отдельных животных за посещение, которое произошло только в первом посещении, только во втором посещении и произошло в обоих посещениях». Также в предоставленном вами документетри посещения.Я рассматриваю три визита.

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

Шаг 1 .Создайте набор необработанных данных

library(data.table)
df = data.table(visit_number = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3), 
                pet = c("Dog", "Rat", "Cat", "Dog", "Chicken", "Cat", "Dog", "Cat", "Fish", "Horse"))

Шаг 2 .Создайте вектор понятных имен столбцов для использования в будущем

cols = c(paste0(rep("Visit", length(unique(df$visit_number))), unique(df$visit_number)))

Шаг 3 .Создайте матрицу внешнего вида домашних животных

df = dcast.data.table(df, pet ~ visit_number, value.var = "pet", fun.aggregate = length)
names(df)[-1] = cols # assign understandable column names

Шаг 4 .Определите домашних животных, которые появлялись во всех посещениях

df[, AllVisits := Reduce(`*`, .SD), .SDcols = cols]

Это дает:

df
       pet Visit1 Visit2 Visit3 AllVisits
1:     Cat      1      1      1         1
2: Chicken      0      1      0         0
3:     Dog      1      1      1         1
4:    Fish      0      0      1         0
5:   Horse      0      0      1         0
6:     Rat      1      0      0         0

Крыса была уникальной для посещения 1, Цыпленок была уникальной для посещения 2, Рыба и Лошадь были уникальными для посещения 3Кошка и собака появлялись во всех посещениях.

Шаг 5 .Получите количество уникальных чисел животных по посещениям и уникальное количество животных, которое появилось во всех посещениях

idx = df[, Reduce(`+`, .SD) == 1, .SDcols = cols]
unlist(c(df[idx, lapply(.SD, function(x) sum(x)), .SDcols = cols], AllVisits = df[, sum(AllVisits)]))

Результат:

Visit1    Visit2    Visit3 AllVisits 
     1         1         2         2 

Дайте мне знать, если это то, что выищите.

PS Код потребуется изменить, если домашние животные могут появляться несколько раз во время посещения.

0 голосов
/ 25 сентября 2018

Если я правильно понял, что вы спрашиваете, вот решение с использованием функций из пакета dplyr:

full_join(filter(df, visit_number == 1), filter(df, visit_number == 2), by = 'pet') %>%
    mutate(visit1 = !is.na(visit_number.x),
           visit2 = !is.na(visit_number.y),
           both = visit1 & visit2) %>% 
    select(-starts_with('visit_number'))

Предоставление:

      pet visit1 visit2  both
1     dog   TRUE   TRUE  TRUE
2     cat   TRUE   TRUE  TRUE
3     rat   TRUE  FALSE FALSE
4 chicken  FALSE   TRUE FALSE
...