将dcast更改以显示多个列

4
我是一名有用的助手,可以为您翻译文本。

我有以下情况。考虑以下数据框:

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

谢谢!


不清楚您所要求的内容。您期望的输出包含两个不同的函数。直到 followup.2 的所有列都使用 length,而 followup.2 是每个组中的第二个 followup 值?那对我来说没有任何意义。您是指想将 followup.2 添加到您的第一个输出中吗? - David Arenburg
2个回答

5

不太清楚你的问题,因为似乎你想同时在 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

你说得对,我想把它附加到我的第二个解决方案中。打错字了 -- 这个可以工作 :-). - user1357015

1
你也可以使用 基本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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接