Подсчитать количество ярлыков на сайте и создать сводную таблицу в R
Ниже приведена часть чего-то похожего на мой набор данных:
require(dplyr)
alldata
site date percent_rank Label
01A 2013-01-01 0.32 Normal
01B 2013-01-01 0.12 Low
01C 2013-01-01 0.76 High
02A 2013-01-01 0 N/A
02B 2013-01-01 0.16 Low
02C 2013-01-01 0.5 Normal
01A 2013-01-02 0.67 Normal
01B 2013-01-02 0.01 Low
01C 2013-01-02 0.92 High
Я назначил каждому проценту_ранка метку на основе значения (от 0 до 0,25 до 0,75 до 1 для трех категорий). Теперь я хотел бы подготовить сводную таблицу в этом формате:
site Low Normal High Missing
01A 32 47 92 194
01B 232 23 17 93
01C 82 265 12 6
где каждый сайт будет иметь количество вхождений низких, нормальных и высоких значений для всех дат с этой меткой сайта (по одному на каждый день года), а значения N/A будут учитываться как "пропущенные" колонка.
Я пробовал следующее:
alldata <- %>% group_by(site) %>% mutate(length(Label == "Low"))
который возвращает общее значение всех записей, а не количество "Низкий" на сайт, и
alldata <- %>% group_by(site) %>% mutate(length(which(Label == "Low")))
который возвращает значение на несколько тысяч больше, чем общее количество записей. Идея состояла в том, чтобы я повторил эту функцию, чтобы создать четыре новых столбца с четырьмя отдельными строками изменения (по одной для каждой категории), и это привело бы к моей сводной таблице. Я также попробовал некоторые варианты aggregate(), хотя компонент функции был для меня менее понятен для того, что я собираюсь сделать. Кажется, что это должно быть довольно простым делом (а group_by хорошо мне помог при расчете процентного ранга и связанных с ним меток), но я пока не смог найти решение. Любые советы очень ценятся!
3 ответа
Мы можем использовать dcast
от data.table
которые также имеют fun.aggregate
и очень быстро.
library(data.table)
dcast(setDT(alldata), site~Label, length)
Или используя dplyr/tidyr
library(dplyr)
library(tidyr)
alldata %>%
group_by(site, Label) %>%
tally() %>%
spread(Label, n)
base R
вариант будет
reshape(aggregate(date~site + Label, alldata, length),
idvar = "site", timevar="Label", direction="wide")
Есть три способа сделать это в dplyr
, Первый является наиболее многословным, а два других используют удобные функции для сокращения кода:
library(reshape2)
library(dplyr)
alldata %>% group_by(site, Label) %>% summarise(n=n()) %>% dcast(site ~ Label)
alldata %>% group_by(site, Label) %>% tally %>% dcast(site ~ Label)
alldata %>% count(site, Label) %>% dcast(site ~ Label)
Чтобы просто создать сводную таблицу, вы можете использовать table
:
with(df, table(site, Label, useNA="ifany"))[, c(2,4,1,3)]
Label
site Low Normal High N/A
01A 0 2 0 0
01B 2 0 0 0
01C 0 0 2 0
02A 0 0 0 1
02B 1 0 0 0
02C 0 1 0 0
данные
df <- read.table(header=T, text="site date percent_rank Label
01A 2013-01-01 0.32 Normal
01B 2013-01-01 0.12 Low
01C 2013-01-01 0.76 High
02A 2013-01-01 0 N/A
02B 2013-01-01 0.16 Low
02C 2013-01-01 0.5 Normal
01A 2013-01-02 0.67 Normal
01B 2013-01-02 0.01 Low
01C 2013-01-02 0.92 High")