更改dcast以显示多个列

时间:2014-12-16 22:18:18

标签: r reshape2

我有以下情况。请考虑以下df:

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

如果我在前6行做dcast:

> 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

谢谢!

2 个答案:

答案 0 :(得分:5)

您不清楚自己的要求,因为您似乎希望同时在dcast中合并两个不同的功能。在我看来,你想要改善你的第一个输出而不是第二个输出。如果是这样,一个简单的解决方案就是为Visit列中的值添加自动索引,然后dcast。这是一个使用data.table包的简单方法(认为输出不是您想要的,因为我还添加了baseline的索引,但它可以帮助您开始)< / p>

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

答案 1 :(得分: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