У меня есть сбалансированная таблица данных, содержащая тысячи фирм с наблюдениями по два года каждая (1 и 2). Для процесса очистки данных мне нужно исключить наблюдения, в которых есть смещение между годами в предположительно постоянной времени.

example <- matrix(c(1,1,2,2,3,3,4,4,1,2,1,2,1,2,1,2,1,1,0,0,0,1,1,0), ncol=3)
colnames(example) <- c('id', 'year', 'supposedly time-constant')
example.table <- data.table(example)
example.table

   id year supposedly time-constant
1:  1    1                        1
2:  1    2                        1
3:  2    1                        0
4:  2    2                        0
5:  3    1                        0
6:  3    2                        1
7:  4    1                        1
8:  4    2                        0

Итак, в приведенной выше таблице фирмы 3 и 4 показывают изменение предположительно постоянной времени, поэтому их необходимо будет удалить. Фирмы 1 и 2 - это то, что я хочу иметь. Мне нужен код / функция, которая позволяет мне чистить мои данные.

Кажется, я достиг предела своих знаний R и надеюсь, что смогу найти здесь помощь - заранее спасибо!

1
M_R_ 1 Май 2019 в 16:28

4 ответа

Лучший ответ

Мы можем использовать dplyr и выбирать группы, которые имеют только одно уникальное значение

library(dplyr)
example.table %>%
   group_by(id) %>%
   filter(n_distinct(`supposedly time-constant`) == 1)


#     id  year `supposedly time-constant`
#  <dbl> <dbl>                      <dbl>
#1     1     1                          1
#2     1     2                          1
#3     2     1                          0
#4     2     2                          0

Та же логика в базе R с использованием ave будет

example.table[with(example.table, ave(`supposedly time-constant`, id, 
             FUN = function(x) length(unique(x))) == 1), ]
3
Ronak Shah 1 Май 2019 в 13:43

Мы можем использовать методы data.table, поскольку это data.table. Сгруппированные по 'id', проверьте, что длина уникальных элементов в supposedly time-constant равна 1, и установите подмножество .SD (Подмножество data.table)

library(data.table)
example.table[, .SD[uniqueN(`supposedly time-constant`) == 1], by = id]
#     id year supposedly time-constant
#1:  1    1                        1
#2:  1    2                        1
#3:  2    1                        0
#4:  2    2                        0

Или немного быстрее вариант будет .I

example.table[example.table[, .I[uniqueN(`supposedly time-constant`)
            == 1], by = id]$V1]
#   id year supposedly time-constant
#1:  1    1                        1
#2:  1    2                        1
#3:  2    1                        0
#4:  2    2                        0
1
akrun 1 Май 2019 в 13:55

Другой dplyr подход с all, который выбирает все группы, которые имеют все 0 или все 1. Это будет неэффективно, если у вас так много предположительно постоянных во времени условий:

    library(dplyr)
    example.table %>% 
       group_by(id) %>% 
       filter(all(`supposedly time-constant`==1) | all(`supposedly time-constant`==0))
    # A tibble: 4 x 3
    # Groups:   id [2]
         id  year `supposedly time-constant`
      <dbl> <dbl>                      <dbl>
    1     1     1                          1
    2     1     2                          1
    3     2     1                          0
    4     2     2                          0
1
NelsonGon 1 Май 2019 в 13:40

Вы можете использовать data.table и концепцию цепочки, чтобы определить, какие ID / фирмы показывают такое изменение:

example.table[, .(unq_val = length(unique(`supposedly time-constant`))), by = .(id)][unq_val >= 2, .(id)]

Вышеприведенную строку кода можно разбить следующим образом: 1. Для каждого идентификатора (в аргументе by), 2. Создайте переменную с именем unq_val, которая подсчитывает общее количество уникальных «предположительно постоянных времени», 3. Затем выбирает только фирмы / идентификаторы, которые содержат значение> = 2 для такой переменной.

Вывод кода:

   id
1:  3
2:  4

Это data.table, который вы можете затем использовать для фильтрации наблюдений из ваших исходных данных.

2
ds_newbie 1 Май 2019 в 13:53