Как найти индексы изменения на основе двух векторов r

#r

#r

Вопрос:

У меня есть два вектора, которые содержат индексы, которые выглядят как

 index A  index B
   1        1
   1        1
   1        1
   1        2
   1        2
   2        1
   2        1
  

Теперь я хочу найти длину каждой комбинации между индексом A и индексом B. Итак, в моем примере есть три уникальные комбинации для индекса A и индекса B, и я хочу получить обратно 3, 2, 2 в векторе. Кто-нибудь знает, как это сделать без цикла for?

РЕДАКТИРОВАТЬ: Итак, в этом примере есть три уникальные комбинации (1 1, 1 2 и 2 1), для которых существует 3 комбинации 1 1, 2 из 1 2 и 2 из 2 1. Поэтому я хочу вернуть 3, 2, 2

Комментарии:

1. 3 для уникальной комбинации. Что обозначают два других 2?

2. первые 3 соответствуют числу 1 1, остальные 2 соответствуют количеству комбинаций 1 2 и 2 1

3. итак, это частоты количества уникальных комбинаций?

4. Да, это действительно то, что я имею в виду

Ответ №1:

Я думаю, это то, что вы хотите:

 library(plyr)
df <- data.frame(index_A = c(1, 1, 1, 1, 1, 2, 2),
                 index_B = c(1, 1, 1, 2, 2, 1, 1))
count(df, vars = c("index_A", "index_B"))
#>   index_A index_B freq
#> 1       1       1    3
#> 2       1       2    2
#> 3       2       1    2
  

Создано 2019-03-17 пакетом reprex (версия 0.2.1)

Я получил это из здесь.

Ответ №2:

В base R мы можем использовать table

 as.data.frame(table(dat))
  

Комментарии:

1. Это супер круто, но я получаю дополнительную строку 2 2 с частотой 0.

2. @yarnabrina table(dat) предоставляет формат, в котором он ищет все комбинации. Если некоторых из них там нет, указывается 0. если это не представляет интереса subset(as.data.frame(table(dat)), Freq > 0)

Ответ №3:

Вы могли бы вставить векторы вместе и вызвать rle

 rle(do.call(paste0, dat))$lengths
# [1] 3 2 2
  

Если вам нужен результат в виде data.frame , сделайте

 as.data.frame(unclass(rle(do.call(paste0, dat))))
#  lengths values
#1       3     11
#2       2     12
#3       2     21
  

данные

 text <- "indexA  indexB
   1        1
   1        1
   1        1
   1        2
   1        2
   2        1
   2        1"

dat <- read.table(text = text, header = TRUE)
  

Ответ №4:

Это как-то халтурно:

 library(dplyr)
df %>% 
  mutate(Combined=paste0(`index A`,"_",`index B`)) %>% 
  group_by(Combined) %>% 
  summarise(n=n())
# A tibble: 3 x 2
  Combined     n
  <chr>    <int>
1 1_1          3
2 1_2          2
3 2_1          2
  

На самом деле можно просто сделать:

 df %>% 
  group_by(`index A`,`index B`) %>% 
  summarise(n=n())
  

Добавление tidyr unite по предложению @kath

 library(tidyr)
df %>% 
  unite(new_col,`index A`,`index B`,sep="_") %>% 
  add_count(new_col) %>% 
  unique()
  

Данные:

 df<-read.table(text="index A  index B
   1        1
               1        1
               1        1
               1        2
               1        2
               2        1
               2        1",header=T,as.is=T,fill=T)
df<-df[,1:2]
names(df)<-c("index A","index B")
  

Комментарии:

1. Вы могли бы заменить mutate на unite() и summarise на count()

2. @kath Я впервые попробовал с unite , но, похоже, для этого нужны символьные данные.

3. Странно, у меня это работает: unite(df, new_col, индекс A , , индекс B , sep = "_")

4. @kath Я добавил эту опцию. Спасибо.

Ответ №5:

Используя dplyr :

 library(dplyr)
count(dat,!!!dat)$n
# [1] 3 2 2