2016-08-20 2 views
0

У меня есть набор данных, подобный этому:Подменю номинальные переменные в R

x <- sample(c("A", "B", "C", "D"), 1000, replace=TRUE, prob=c(0.1, 0.2, 0.65, 0.05)) 
y <- sample(1:40, 1000, replace=TRUE) 
d <- data.frame(x,y) 

str(d) 
'data.frame': 1000 obs. of 2 variables: 
$ x: Factor w/4 levels "A","B","C","D": 1 3 3 2 3 3 3 3 4 3 ... 
$ y: int 28 35 14 4 34 36 30 35 26 9 ... 

table(d$x) 
A B C D 
115 204 637 44 

Таким образом, в моем реальном наборе данных у меня есть несколько тысяч этих категорий (A, B, C, D).

str() моих реальных данных

str(realdata) 
data.frame': 346340 obs. of 91 variables: 
$ author  : Factor w/ 42590 levels "-jon-","--LZR--",..: 1962 3434 1241 7666 6235 2391 1196 2779 1881 339 ... 
$ created_utc : Factor w/ 343708 levels "2015-05-01 02:00:41",..: 14815 23163 2281 3569 5922 7211 15783 5512 13485 8591 ... 
$ group : Factor w/ 5 levels "xyz","abc","bnm",..: 2 2 2 2 2 2 2 2 2 2 ... 
.... 

Теперь я хочу, чтобы подмножество данных, так что я только строки тех $ авторов (или $x в d dataframe) в моем новом dataframe, которые имеют более чем 100 записей.

Я попытался следующие:

dnew <- subset(realdata, table(realdata$author) > 100) 

Это дает мне результат, но, кажется, были включены не все записи авторов. Хотя это должно быть больше, я просто получаю 1,3% строк полного набора данных. Я проверил его вручную (с помощью excel), и он должен быть более чем (примерно 30%). Ручной анализ показал, что 1,2% от $ author составляют 30% записей. Кажется, он просто дал мне один ряд с $ author, у которого более 100 записей, но не все его записи.

Знаете ли вы, как это исправить?

ответ

1

кадр I. Данные d с четырьмя уровнями

table(d$x) 

    # A B C D 
    # 92 232 630 46 

II. Проверка уровня, превышающего 100 записей

which(table(d$x)>100) 
    # B C 
    # 2 3 

III. Подмножество d кадр данных, имеющий только записи, относящиеся к уровням, которые имеют более 100 записей, т.е.level B и level C

result <- d[ d$x %in% names(table(d$x))[table(d$x) > 100] , ] 
    dim(result) 
    # [1] 862 2 

    str(result) 
    # 'data.frame': 862 obs. of 2 variables: 
    # $ x: Factor w/ 4 levels "A","B","C","D": 3 2 3 3 2 2 2 3 3 3 ... 
    # $ y: int 29 32 27 40 30 38 8 16 2 23 ... 

Уровень A и D все еще сохраняется с 0 records

table(result$x) 

    # A B C D 
    # 0 232 630 0 

IV. Удаление уровней с 0 записями с использованием factor()

result$x <- factor(result$x) 

    str(result) 
    # 'data.frame': 860 obs. of 2 variables: 
    # $ x: Factor w/ 2 levels "B","C": 2 2 1 2 1 2 2 2 1 2 ... 
    # $ y: int 29 32 27 40 30 38 8 16 2 23 ... 

    table(result$x) 
    # B C 
    # 232 630 
+1

спасибо, что сработало !!!! –

+1

@akrun У меня нет подсказки, что вы добавили, что для моего ответа я использовал комбинацию из двух ссылок, я попробовал его, а затем опубликовал, вот это http://stackoverflow.com/questions/24835233/subset-based-on- частотный уровень http://stackoverflow.com/questions/1195826/drop-factor-levels-in-a-subsetted-data-frame Ваш ответ на базу R также работает. Я тоже это проверил, уровни все еще сохранялись данных, поэтому я бросил их по второй ссылке. Спасибо. –

3

Мы можем сделать это легко с data.table. Преобразование 'data.frame' к 'data.table' (setDT(d), сгруппированных по 'х', if число наблюдений превышает 100, то подмножеству в Data.table (.SD)

library(data.table) 
ddt <- setDT(d)[, if(.N > 100) .SD, x] 

Или, если мы используем dplyr, тот же подход может быть использован.

library(dplyr) 
dpl <- d %>% 
     group_by(x) %>% 
     filter(n() > 100) %>% 
     droplevels() 
str(dpl) 
#Classes ‘grouped_df’, ‘tbl_df’, ‘tbl’ and 'data.frame': 866 obs. of 2 variables: 
#$ x: Factor w/ 2 levels "B","C": 1 1 2 1 1 2 2 2 2 2 ... 
# $ y: int 25 25 13 11 2 32 12 15 12 3 ... 

Кроме того, при использовании base R, то table может б е полезно

v1 <- table(d$x) 
d1 <- subset(d, x %in% names(v1)[v1 > 100]) 

В столбце «х» factor, когда мы subset набор данных, уровни сохраняются, чтобы удалить, что использование droplevels

d2 <- droplevels(d1) 

В ОП не ставил seed, выход будет отличаться для каждого человека.

str(d2) 
#'data.frame': 866 obs. of 2 variables: 
#$ x: Factor w/ 2 levels "B","C": 1 1 2 1 1 2 2 2 2 2 ... 
#$ y: int 25 25 13 11 2 32 12 15 12 3 ... 
+0

Я пробовал версию с dplyr. Он работает с тестовым фреймворком. Увы, я получаю сообщение об ошибке, применяя его к моему реальному набору данных: Ошибка: недопустимый индекс типа «целое». Я проверил, что $ author является фактором, равно как и x. Я использовал следующую команду: auth <- realdata%>% group_by (realdata $ author)%>% filter (n()> 100) –

+0

@ 8bytez Я также предоставил еще два решения: один с 'data.table', а другой в 'subset'. Решение, которое вы приняли, использует ту же логику, что и я. Это так безумно. – akrun

+0

@ 8bytez Вы даже не используете синтаксис в моем коде 'group_by (realdata $ author)' не используется мной. – akrun