2014-12-16 5 views
3

У меня есть следующая ситуация. Рассмотрим следующую ДФ:Изменение dcast для отображения нескольких столбцов

mymatrix <- as.data.frame(matrix(data = 0, nrow = 7, ncol = 4)) 
colnames(mymatrix) <- c("Patient", "marker", "Number", "Visit") 

mymatrix[,1] <- c("B1","B1","C1","C1","D1","D1","D1") 
mymatrix[,2] <- c("A","A","A","A","A","A","A") 
mymatrix[,3] <- c(1,0,0,15,1,2,13) 
mymatrix[,4] <- c("baseline","followup","baseline","followup","baseline","followup","followup") 

> mymatrix 
    Patient marker Number Visit 
1  B1  A  1 baseline 
2  B1  A  0 followup 
3  C1  A  0 baseline 
4  C1  A  15 followup 
5  D1  A  1 baseline 
6  D1  A  2 followup 
7  D1  A  13 followup 

Если я dcast на первых 6 строк я получаю:

> dcast(mymatrix[1:6,], Patient +marker~Visit, value.var = "Number") 
    Patient marker baseline followup 
1  B1  A  1  0 
2  C1  A  0  15 
3  D1  A  1  2 

Если я dcast на все строки я получаю:

> dcast(mymatrix, Patient +marker~Visit, value.var = "Number") 
Aggregation function missing: defaulting to length 
    Patient marker baseline followup 
1  B1  A  1  1 
2  C1  A  1  1 
3  D1  A  1  2 

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

Patient marker baseline followup.1 followup.2 
1  B1  A  1  0  NA 
2  C1  A  0  15  NA 
3  D1  A  1  2  13 

Спасибо!

+0

Это не ясно, что вы просите. Желаемый вывод содержит две разные функции. Все столбцы до 'followup.2' используют' length', а 'followup.2' - второе значение' followup' в каждой группе? Это не имеет никакого смысла для меня. Вы хотите сказать, что хотите добавить 'followup.2' в свой первый выход? –

ответ

4

Непонятно, что вы просите, потому что кажется, что вы хотите объединить две разные функции в dcast одновременно. Мне кажется, что вы хотите улучшить свой первый выход вместо второго. Если это так, простым решением было бы просто добавить автоматический индекс к значениям в столбце Visit, а затем dcast. Вот простой подход с использованием data.table пакета (думал, вывод не совсем то, что вы хотите, потому что я также добавил индекс baseline, но он может получить вы начали)

library(data.table) 
setDT(mymatrix)[, Visit := paste(Visit, seq_len(.N), sep = "."), list(Patient, Visit)] 
dcast.data.table(mymatrix, Patient + marker ~ Visit, value.var = "Number") 

# Patient marker baseline.1 followup.1 followup.2 
# 1:  B1  A   1   0   NA 
# 2:  C1  A   0   15   NA 
# 3:  D1  A   1   2   13 
+0

Вы правы, я хотел, чтобы он присоединился к моему второму решению. Typo - это работает :-). – user1357015

1

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

d1 <- transform(mymatrix, Visit=paste0(Visit,ave(seq_along(Number), 
             Patient, Visit, FUN=seq_along))) 

reshape(d1, idvar=c('Patient', 'marker'), timevar='Visit', direction='wide') 
# Patient marker Number.baseline1 Number.followup1 Number.followup2 
#1  B1  A    1    0    NA 
#3  C1  A    0    15    NA 
#5  D1  A    1    2    13 

Или dplyr/tidyr

library(dplyr) 
library(tidyr) 
mymatrix %>% 
     group_by(Patient, Visit) %>% 
     mutate(indx=row_number()) %>% 
     ungroup() %>% 
     unite(Visit1, Visit, indx) %>% 
     spread(Visit1, Number) 
# Patient marker baseline_1 followup_1 followup_2 
#1  B1  A   1   0   NA 
#2  C1  A   0   15   NA 
#3  D1  A   1   2   13