R: поиск пересечений в подмножестве по другому столбцу - PullRequest
0 голосов
/ 04 мая 2020

У меня есть набор данных age_structure примерно так:

MACHINE_NUMBER | MACHINE_KIND
         12345 | A
         12346 | A
         12347 | A
         12345 | B
         12348 | B

Мне нужно как-то определить, какие MACHINE_NUMBER находятся в обоих подмножествах MACHINE_KIND. В этом случае должно возникнуть только 12345. До сих пор я пытался выполнить поднабор фрейма данных следующим образом, но поскольку столбец MACHINE_KIND отсутствует в подмножестве, R выдает ошибку:

common_numbers <- Reduce(intersect, list(subset(age_structure$MACHINE_NUMBER, MACHINE_KIND == "A"), subset(age_structure$MACHINE_NUMBER, MACHINE_KIND == "B")))

object 'MACHINE_KIND' not found

Определение имени age_structure как части условия запускает код без ошибок, но полученный common_numbers является пустым.

common_numbers <- Reduce(intersect, list(subset(age_structure$MACHINE_NUMBER, age_structure$MACHINE_KIND == "A"), subset(age_structure$MACHINE_NUMBER, age_structure$MACHINE_KIND == "B")))

MACHINE_NUMBER и MACHINE_KIND являются факторами. Что делать, желательно?

Ответы [ 4 ]

0 голосов
/ 04 мая 2020
# example dataset
dt = read.table(text = "
MACHINE_NUMBER | MACHINE_KIND
12345 | A
12346 | A
12347 | A
12345 | B
12348 | B
", header=T, sep="|")

Один вариант с использованием базы R

# create table based on unique rows of your dataframe
tbl = table(unique(dt)$MACHINE_NUMBER)

# get those that have 2 rows (i.e. belong in both groups)
names(tbl)[tbl == 2]

# [1] "12345"

Другой вариант с использованием dplyr:

library(dplyr)

dt %>%
  group_by(MACHINE_NUMBER) %>%
  summarise(Counts = n_distinct(MACHINE_KIND)) %>%
  filter(Counts == 2)

# # A tibble: 1 x 2
#      MACHINE_NUMBER Counts
#              <dbl>  <int>
#   1          12345      2

Обратите внимание, что если у вас несколько групп, вы можете использовать >= 2, вместо == 2.

0 голосов
/ 04 мая 2020

Base R однострочный:

unique(Reduce(function(x, y){setdiff(x, y)}, split(df$MACHINE_NUMBER, df$MACHINE_NUMBER)))
0 голосов
/ 04 мая 2020

Вы можете использовать пакет dplyr и пакет stringr, чтобы проверить, имеет ли MACHINE_NUMBER оба (или более) вида.

library(tidyverse)
library(stringr)

a <- tibble::tribble(
    ~MACHINE_NUMBER, ~MACHINE_KIND,
    12345L,           "A",
    12346L,           "A",
    12347L,           "A",
    12345L,           "B",
    12348L,           "B"
) 

a %>% 
    group_by(MACHINE_NUMBER) %>% 
    summarize(both = if_else(all(str_detect(MACHINE_KIND, unique(a$MACHINE_KIND))), "yes", "no"))
#> # A tibble: 4 x 2
#>   MACHINE_NUMBER both 
#> *          <int> <chr>
#> 1          12345 yes  
#> 2          12346 no   
#> 3          12347 no   
#> 4          12348 no

Затем вы можете отфильтровать их, если хотите, на всякий случай, если вы хотите провести больше анализа с вашими данными.

0 голосов
/ 04 мая 2020

Вы можете посчитать количество различных MACHINE_KIND, которые вы найдете для каждого MACHINE_NUMBER

library(data.table)
df[,n := uniqueN("MACHINE_KIND"), by = "MACHINE_NUMBER"][n>=2]

Если вас интересуют только категории A и B, сначала отфильтруйте:

library(data.table)
df["MACHINE_KIND" %in% c("A","B"),n := uniqueN("MACHINE_KIND"), by = "MACHINE_NUMBER"][n>=2]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...