2015-09-02 8 views
0

У меня есть ФР следующим образом:Выявление уникальных наблюдений, которые удовлетворяют двум условиям, а затем удалить R

data 
    names fruit 
7 john apple 
13 john orange 
14 john apple 
2 mary orange 
5 mary apple 
8 mary orange 
10 mary apple 
12 mary apple 
1 tom apple 
6 tom apple 

Я хотел бы сделать две вещи. Сначала подсчитайте количество уникальных наблюдений, в которых есть как яблоко, так и оранжевое (например, 2 mary и john).

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

Это то, что я пытался

toremove<-unique(data[data$fruit=='apple' & data$fruit=='orange',"names"]) ##this part doesn't work, if it had I would have used the below code to remove the names identified 
data2<-data[!data$names %in% toremove,] 

Действительно, я хотел использовать grepl, потому что мои реальные данные немного более сложным, чем фрукты. Это то, что я пытался (превратить в data.table первый)

data1<-data.table(data1) 
z<-data1[,ind := grepl('app.*? & orang.*?', fruit), by='names'] ## this works fine when i just use 'app.*?' but collapses when I try to add the & sign, so I'm making an error with the operator. In addition the by='names' doesn't work out for me, which is important. My plan here was to create an indicator (if an individual has an apple and an orange, then they get an indicator==1 and I would then filter them out on the basis of this indicator). 

Так, в целом моя проблема заключается в выявлении людей, которые имеют как яблоко и апельсин. Это кажется таким простым, поэтому не стесняйтесь направить меня к ресурсу, который может научить меня этому!

требуемого выход

names fruit 
1 tom apple 
6 tom apple 
+0

Таким образом, ваш желаемый результат не включает в себя подсчет уникальных наблюдений? Так почему же пытаются подсчитать в первую очередь? –

+0

Я хочу быть в состоянии подсчитать, сколько людей имели как яблоки, так и апельсины. Если бы у меня был показатель для этих условий, я бы просто подмножество на них и подсчитал их. Или я мог бы ограничить свой df только людьми с яблоками и апельсинами и подсчитать количество уникальных людей там. Затем, когда я получаю окончательный результат только для яблочных людей, простое вычитание подскажет мне, сколько у людей было как апельсинов, так и яблок. Поэтому я сосредоточен на том, как идентифицировать людей из яблока и апельсина. Я мог бы понять, как считать их после этого. – user2363642

ответ

6

Если вы ищете только для имен только apple s с, вот простой data.table подход

setDT(data)[ , if(all(fruit == "apple")) .SD, by = names] 
# names fruit 
# 1: tom apple 
# 2: tom apple 

Для уникальных наблюдений, которые имеют как «яблоко» и «апельсин» подсчитывать, вы могли бы сделать что-то вроде

data[, any(fruit == "apple") & any(fruit == "orange"), by = names][, sum(V1)] 
## [1] 2 

Наконец, если все, что вы ищете это пользователи только один уникальный fruit, вы можете попробовать кондиционировать с помощью uniqueN из devel version on GH (или length(unique()))

data[, if(uniqueN(fruit) < 2L) .SD, by = names] 
# names fruit 
# 1: tom apple 
# 2: tom apple 
+0

Вторая строка кода отличная, спасибо. Первое хорошо и просто, но мои данные слишком сложны, чтобы использовать его. Я изменил вашу вторую строку кода, чтобы выглядеть так, и, похоже, она работает: data [, any (grepl ('app. *?', Fruit)) & any (grepl ('orang. *?', Fruit)), by = names] – user2363642

+2

Итак, вы можете настроить первую строку на что-то вроде 'setDT (data) [, if (sum (grepl (« apple », fruit)) == .N) .SD, by = names]' too in чтобы получить желаемый результат –

0

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

data = 
    read.table(text=" 
      names fruit 
      7 john apple 
      13 john orange 
      14 john apple 
      2 mary orange 
      5 mary apple 
      8 mary orange 
      10 mary apple 
      12 mary apple 
      1 tom apple 
      6 tom apple 
      21 kathy orange", header=T) 

# names fruit 
# 7 john apple 
# 13 john orange 
# 14 john apple 
# 2 mary orange 
# 5 mary apple 
# 8 mary orange 
# 10 mary apple 
# 12 mary apple 
# 1 tom apple 
# 6 tom apple 
# 21 kathy orange 


library(dplyr) 

data %>% 
    group_by(names) %>%       # for each user name 
    mutate(N_dist = n_distinct(fruit),    # count distinct number of fruits 
     N_oranges = sum(fruit=="orange")) %>% # count number of oranges 
    filter(N_oranges == 0 & N_dist < 2) %>%  # keep users with no oranges and no both fruits 
    select(names, fruit) 


# names fruit 
# 1 tom apple 
# 2 tom apple 

Обратите внимание, что в точке перед применением фильтра набора данных выглядит следующим образом:

# names fruit N_dist N_oranges 
# 1 john apple  2   1 
# 2 john orange  2   1 
# 3 john apple  2   1 
# 4 mary orange  2   2 
# 5 mary apple  2   2 
# 6 mary orange  2   2 
# 7 mary apple  2   2 
# 8 mary apple  2   2 
# 9 tom apple  1   0 
# 10 tom apple  1   0 
# 11 kathy orange  1   1 

, где вы можете получить уникальные имена, которые имеют как фрукты, или пользователей, которые имеют апельсины.

+0

Вы считаете, что значения всегда являются «яблоком» или «оранжевым» здесь. Не говоря уже о том, что этот метод не удастся для людей, у которых есть только «оранжевый» –

+0

Если есть еще один фрукт, код будет исключать пользователей, у которых есть 2 из 3 плодов. Этот фильтр (n> 1) выполняет эту работу. Но, действительно, он основан на конкретном примере, предоставленном пользователем. – AntoniosK

+0

Почему это будет не только оранжевым? – AntoniosK

 Смежные вопросы

  • Нет связанных вопросов^_^