我有一个R数据框:
> tab1
pat t conc
1 P1 0 788
2 P1 5 720
3 P1 10 655
4 P2 0 644
5 P2 5 589
6 P2 10 544
我正在尝试为conc
创建一个新列,作为每个患者conc
= 0的t
的百分比。除了许多其他事情,我还尝试过:
tab1$conct0 <- tab1$conc / tab1$conc[tab1$t == 0 & tab1$pat == tab1$pat]
但我显然已经使用了正确的代码,这意味着“conc WHERE t == 0并且pat = =拍拍这个特定的行”
我确信我可以使用for循环或其他东西,但希望有更容易的东西?
由于
答案 0 :(得分:2)
使用plyr:
library(plyr)
ddply(tab1, "pat", transform, conct0 = conc / conc[t == 0])
答案 1 :(得分:1)
我会找到每位患者的起始浓度:
startConc <- tab1[tab1$t == 0,]
给出(来自您的示例数据)
pat t conc
1 P1 0 788
4 P2 0 644
之后,您可以使用apply
newconc <- apply(tab1, 1, function(x){as.numeric(x[3])/startConc[startConc$pat==x[1],3]})
给你
[1] 1.0000000 0.9137056 0.8312183 1.0000000 0.9145963 0.8447205
答案 2 :(得分:1)
这是一种稍微简单的方法,但在这种情况下有效:
xt <- xtabs(conc~t+pat,tab1)
tab1$conct0 <- as.numeric(t(t(xt)/xt[1,])) # need to use transpose because of the way matrix vector indexing works
xt[1,]
代表t=0
的行;你也可以使用xt["0",]
。
修改强>
更强大的方式:
tabt <- subset(tab1,t==0)
names(tabt)[3] <- "conct0"
tab1 <- merge(tab1,tabt[,c(1,3)])
tab1$conct0 <- tab1$conc/tab1$conct0
答案 3 :(得分:1)
我会使用tapply
。鉴于您的数据:
tab1 <- data.frame(
pat = c(rep("P1", 3), rep("P2", 3)),
t = c(0, 5, 10, 0, 5, 10),
conc = c(788, 720, 655, 644, 589, 544))
这个单行代码将按照你在帖子中暗示的方式为你做这件事:
> tab1$conc / tab1$conc[tab1$t == 0][tapply(tab1$pat, tab1$pat)]
[1] 1.0000000 0.9137056 0.8312183 1.0000000 0.9145963 0.8447205
没有任何函数的tapply
创建一个与每行的患者ID(数字)匹配的行索引。我发现这种方法相当快速有用。但这假设您的患者'被命令。如果这是一个问题,我们可以确保它们符合患者的ID顺序:
> tab1$conc / tab1$conc[tab1$t == 0][order(unique(tab1$pat))][tapply(tab1$pat, tab1$pat)]
[1] 1.0000000 0.9137056 0.8312183 1.0000000 0.9145963 0.8447205
如果您经常使用它,我会为它编写一个函数,例如:
myFract <- function(obj, x = "conc", id = "pat", time = "t", start = NULL) {
if (is.null(start)) start <- min(obj[, time])
ii <- which(obj[, time] == start)
ii <- ii[order(unique(obj[, id]))][tapply(obj[, id], obj[, id])]
obj[, x] / obj[ii, x]
}
这样:
> myFract(tab1)
[1] 1.0000000 0.9137056 0.8312183 1.0000000 0.9145963 0.8447205
答案 4 :(得分:0)
如果您可以安全地假设您的注意力不会随着时间的推移而增加,那么最短且最快的计算答案就是......
tab1$concp <- ave(tab1$conc, tab1$pat, FUN = function(x) x/max(x))