Группировать строки в кадре данных по общим элементам, используя R - PullRequest
0 голосов
/ 02 мая 2018

У меня есть набор данных, в котором разные строки имеют разные комбинации элементов, и я хочу вытащить группы строк, которые имеют одинаковые комбинации элементов. Для этого примера набор данных:

id <- c("A", "B", "C", "D")
X1 <- c(NA,NA,NA,"X1")
X2 <- c(NA,NA,"X2","X2")
X3 <- c("X3","X3","X3","X3")
X4 <- c("X4", "X4", "X4", "X4")
df <- data.frame(id,X1,X2,X3,X4)

> df
   id   X1   X2 X3 X4
   1  A <NA> <NA> X3 X4
   2  B <NA> <NA> X3 X4
   3  C <NA>   X2 X3 X4
   4  D   X1   X2 X3 X4

Я хочу быть в состоянии вытащить

  • какие идентификаторы имеют X1 & X2 & X3 & X4 (D)
  • какие идентификаторы имеют! X1 & X2 & X3 & X4 (C)
  • какие идентификаторы имеют! X1 &! X2 & X3 & X4 (A и B).

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

df.list <- split(df, seq(nrow(df)))
dfComplete.list <- lapply(df.list, function(remNA) remNA[,colSums(is.na(remNA)) < nrow(remNA)])

что оставляет меня с

> dfComplete.list
$`1`
  id X3 X4
1  1 X3 X4

$`2`
  id X3 X4
2  2 X3 X4

$`3`
  id X2 X3 X4
3  3 X2 X3 X4

$`4`
  id X1 X2 X3 X4
4  4 X1 X2 X3 X4

Я озадачен тем, куда идти отсюда. Есть ли способ сгруппировать кадры данных в списке на основе общих элементов / столбцов?

Реальный набор данных, с которым я работаю, на самом деле имеет элементы / столбцы с X7 по X17, и каждый идентификатор имеет где-то от 1 до 4 элементов, поэтому идеальное решение могло бы идентифицировать все комбинации элементов, присутствующих в моих данных.

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

id <- c("A", "A", "B", "B", "C", "C", "C", "D", "D", "D", "D")
elements <- c("X3", "X4", "X3", "X4", "X2", "X3", "X4", "X1", "X2", "X3", "X4")
dataLong <- data.frame(id, elements)

> dataLong
  id elements
1   A       X3
2   A       X4
3   B       X3
4   B       X4
5   C       X2
6   C       X3
7   C       X4
8   D       X1
9   D       X2
10  D       X3
11  D       X4

Заранее спасибо за помощь!

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

Я так понимаю, вы хотите считать уникальные комбинации. Вот как бы я это сделал

library(dplyr)
library(tidyr)

dataLong %>% mutate(value=1) %>% 
  spread(elements, value) %>% 
  select(-id) %>% 
  group_by_all() %>% 
  summarise(count=n()) %>% ungroup()
#> # A tibble: 3 x 5
#>      X1    X2    X3    X4 count
#>   <dbl> <dbl> <dbl> <dbl> <int>
#> 1     1     1     1     1     1
#> 2    NA     1     1     1     1
#> 3    NA    NA     1     1     2
0 голосов
/ 03 мая 2018

Вы можете использовать tidyverse для этого! Использование arrange() немного излишне, но я хотел показать вам эту опцию, так как она упорядочит ваш фрейм данных, чтобы отразить интересующие вас группы (вы можете думать об этом как о некой вложенной сортировке). Это может быть все, что вам нужно.

Если вам нужны фактические значения, а также столбец, в котором указано, какие идентификаторы соответствуют каким комбинациям, просто запустите полный код, приведенный ниже. Обратите внимание, что вам придется добавить все ваших переменных (X7:X17) в ваш полный код. Вы также захотите использовать stringsAsFactors = FALSE при объявлении своего фрейма данных, что в целом является хорошей практикой.

# Your example dataframe. Make sure to set stringsAsFactors = FALSE
id <- c("A", "B", "C", "D")
X1 <- c(NA,NA,NA,"X1")
X2 <- c(NA,NA,"X2","X2")
X3 <- c("X3","X3","X3","X3")
X4 <- c("X4", "X4", "X4", "X4")
df <- data.frame(id,X1,X2,X3,X4, stringsAsFactors = FALSE)

# We group rows by all unique combinations and then collapse those rows, 
# while recording which ids belong to which grouping, and how many there are 
# in each.
library(tidyverse)
ndf <- arrange(df, X1,X2,X3,X4) %>%
       group_by(X1,X2,X3,X4) %>%
       summarise(num = n(), id = paste(id, collapse=","))

# Output:
# A tibble: 3 x 6
# Groups:   X1, X2, X3 [?]
  X1    X2    X3    X4      num id   
  <chr> <chr> <chr> <chr> <int> <chr>
1 X1    X2    X3    X4        1 D    
2 <NA>  X2    X3    X4        1 C    
3 <NA>  <NA>  X3    X4        2 A,B  
0 голосов
/ 03 мая 2018

Функция reshape2::dcast может помочь преобразовать данные из длинного формата в формат, ожидаемый OP.

#Data
id <- c("A", "A", "B", "B", "C", "C", "C", "D", "D", "D", "D")
elements <- c("X3", "X4", "X3", "X4", "X2", "X3", "X4", "X1", "X2", "X3", "X4")
dataLong <- data.frame(id, elements, stringsAsFactors = FALSE)

library(reshape2)

#Use dcast to get the result
dataLong %>% dcast(id~elements)
#   id   X1   X2 X3 X4
# 1  A <NA> <NA> X3 X4
# 2  B <NA> <NA> X3 X4
# 3  C <NA>   X2 X3 X4
# 4  D   X1   X2 X3 X4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...