繁体   English   中英

使用每一行的条件在data.frame中创建一个新列

[英]Create a new column in data.frame using conditions of each row

我有一个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的百分比conct = 0为每一个病人。 以及许多其他事情,我尝试过:

tab1$conct0 <- tab1$conc / tab1$conc[tab1$t == 0  & tab1$pat == tab1$pat]

但是我显然与正确的代码相距甚远,这意味着“对于此特定行,conc WHERE t == 0 AND pat == pat”

我确定我可以使用for循环之类的东西,但希望有更简单的东西吗?

谢谢

与plyr:

library(plyr)
ddply(tab1, "pat", transform, conct0 = conc / conc[t == 0])

我会发现每个患者的起始浓度:

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

一种临时的方式可以做到这一点,但是在这种情况下可以工作:

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

我会用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已订购。 如果这是一个问题,我们可以确保它们符合患者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

如果您可以安全地认为自己的注意力不会随着时间的流逝而上升,那么为此计算出的最短和最快的答案就是...

tab1$concp <- ave(tab1$conc, tab1$pat, FUN = function(x) x/max(x))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM