#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