2014-10-10 4 views
1

Я просматривал сообщения о суммировании данных, но, похоже, не нашел того, что искал.Как вы суммируете столбцы на основе уникальных идентификаторов, не зная идентификаторов в R?

Я хочу создать сводный «счет-стол», который позволит мне увидеть, как часто пациенту назначают определенные лекарства. Тот факт, что некоторые пациенты получали сразу несколько лекарств, не имеет значения, потому что я просто хочу получить сводку всего лекарственного средства, а затем вычислить, какой процент каждого класса лекарств относится ко всем лекарствам. Проблема в том, что я не знаю названий возможных лекарств, они «скрыты» где-то в data.frame, поэтому я должен указать, какие столбцы R должны будут сначала просмотреть, чтобы создать «список», посредством которой он может суммировать столбцы.

Я ожидаю, что это указывает на пакет plyr, но мои попытки правильно использовать функции в нем до сих пор не работали.

Мой df выглядит как этот

x <- sample(letters[1:4], 20, replace = TRUE) 
y <- sample(letters[1:5], 20, replace = TRUE) 
z <- sample(letters[1:6], 20, replace = TRUE) 
df<-data.frame(x,y,z) 
head(df) 
    x y z 
1 a a f 
2 a c d 
3 b b e 
4 c d b 
5 a a b 
6 c d d 

, как вы можете видеть, data.frame содержит три колонки, которые имеют одни и те же, но и разные буквы, с указанием названия препарата данного.

Что я сейчас хотел бы сделать, это создать список уникальных персонажей,

unique(x) 
unique(y) 
unique(z) 

который служит мой список ссылок, с помощью которого R может затем суммировать счетчики в каждом столбце.

summary(df) 

возвращает сводку отсчетов каждого столбца, но не каждый сам ID, а также без процента от всех уникальных подсчетов.

Я также попытался следующие, который вроде идет в правильном направлении, но в идеале, я хотел бы иметь список уникальных персонажей, которые я могу подать в length аргумент

ddply(df, .(x), summarize, counts=length(unique(y))) 

Любой Идея, как я могу это сделать? Помощь очень ценится.

+1

sapply (Д.Ф., функция (х) имен (таблица (х))) –

+0

@ BondedDust Я бы использовал 'lapply' вместо' sapply'. Если каждый 'names (table (x))' возвратится вектор такой же длины, то результатом будет массив вместо списка, и это может вызвать проблемы, если вам нужно впоследствии обработать этот объект. – nicola

+0

Вправо. Может даже использовать 'lapply (df, function (x) list (nams = unique (x), count = length (unique (x))) –

ответ

1

Если вы просто хотите иметь счетчик для всей dataframe, вы можете использовать table(unlist(df)) (смотрите также @ ответ goctlr в) &, если вы хотите иметь вероятность: prop.table(table(unlist(df))). Когда вы также хотите получить счет для отдельных столбцов, это становится сложнее.

Чтобы получить счетчик для каждого столбца и общего количества, я написал следующую функцию:

# some reproducible data: 
set.seed(1) 
x <- sample(letters[1:4], 20, replace = TRUE) 
y <- sample(letters[1:5], 20, replace = TRUE) 
z <- sample(letters[1:6], 20, replace = TRUE) 
df <- data.frame(x,y,z) 

# the function 
func <- function(x) { 
    x2 <- data.frame() 
    nms <- names(x) 
    id <- sort(unique(unlist(x))) 
    for(i in 1:length(id)) { 
    for(j in 1:length(nms)) { 
     x2[i,j] <- sum(x[,j] %in% id[i]) 
    } 
    } 
    names(x2) <- nms 
    x2$total <- rowSums(x2) 
    x2 <- cbind(id,x2) 
    assign("dat", x2, envir = .GlobalEnv) 
} 

Выполнение функции с func(df) даст вам dataframe dat в вашей глобальной envirenment:

> dat 
    id x y z total 
1 a 4 4 3 11 
2 b 5 5 2 12 
3 c 5 4 4 13 
4 d 6 4 5 15 
5 e 0 3 5  8 
6 f 0 0 1  1 

После этого вы можете рассчитать проценты, например, dplyr:

library(dplyr) 
dat <- dat %>% mutate(xperc=round(100*x/sum(total),1), 
         yperc=round(100*y/sum(total),1), 
         zperc=round(100*z/sum(total),1), 
         perc=round(100*total/sum(total),1)) 

что приводит:

> dat 
    id x y z total xperc yperc zperc perc 
1 a 4 4 3 11 6.7 6.7 5.0 18.3 
2 b 5 5 2 12 8.3 8.3 3.3 20.0 
3 c 5 4 4 13 8.3 6.7 6.7 21.7 
4 d 6 4 5 15 10.0 6.7 8.3 25.0 
5 e 0 3 5  8 0.0 5.0 8.3 13.3 
6 f 0 0 1  1 0.0 0.0 1.7 1.7 
+0

Jaap, это отличная функция! Я действительно буду использовать это довольно много, так как это отличный способ быстро обобщить факторы, чтобы получить обзор что происходит в df! Однако у меня небольшая проблема. При применении второй части вашего ответа я получаю сообщение об ошибке «Ошибка: не удалось найти функцию«%>% ». Любые идеи почему? Кроме того, есть в любом случае, можно фактически добавить столбец к 'dat' df, который затем показывает процент от общего числа? Или я должен просто сохранить измененный 'dat' как' dat2', а затем 'data.frame (dat, dat2)'? Спасибо за отличный ответ! – OFish

+0

Ahhh, глупый я. Я набрал 'library (plyr)', а не 'dplyr'! Моя вина. Сожалею!!! У меня есть еще маленький вопрос, потому что, возможно, я не был ясен. В идеале, я хотел бы иметь процент переменной 'a' суммы столбца' total'. Я переписал мутацию на 'dat2 <- dat %>% mutate (Percentage = 100 * total/sum (total)' - это правильно? Он выглядит нормально ... Спасибо за ваше время и помощь! – OFish

+1

@OFish Это правильно. путь: вы забыли ')' в конце вашего кода в своем последнем комментарии) – Jaap

1

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

table(unlist(df)) 

Чтобы получить процент всего на счету, сохранить результат и использовать prop.table функцию:

tout <- table(unlist(df)) 
prop.table(tout) 
+0

Благодаря @goctlr это удобная небольшая функция.Лично я нахожу, что ответ Яапа дает формат, это самое приятное, но хорошо иметь функцию 'prop.table'. Спасибо за ваше время и помощь! – OFish

+1

Приятный и простой ответ. Однако я понял, что @OFish также хотел подсчеты для отдельных столбцов. Вот почему я не дал этого ответа. Я также включил функции 'table' &' prop.table' в свой ответ, чтобы сделать его более полным. – Jaap

Смежные вопросы