【问题标题】:loops with data from a matrix使用来自矩阵的数据循环
【发布时间】:2013-05-11 12:36:39
【问题描述】:

我有一个数据库,我将其集中在一个名为 DB 的矩阵中,如下所示:

         PN        time.state.2 STATUS
   [1,] 6954010001            0    3.0
   [2,] 6954010001            3    3.5
   [3,] 6954010001            6    3.5
   [4,] 6954010001            9    3.5
   [5,] 6954010001           12    3.5

其中有许多受试者,并且每个受试者都登记了不止一行(登记了状态的患者的不同就诊)。

如果同一患者在随后的访问中增加自己的 STATUS 值,我想创建一个 for 循环来创建一个名为“progression”的对象。

我不明白如何将患者的 PN 代码分配给索引“i”,以允许在完成与患者时继续前进。

例如,对于一个在 time.state.2 对象突出显示的每个时间点具有这些 SCORE 值的患者,我希望当他的 SCORE 值与该患者的第一个时间点相比增加 1 点时,该患者被认为是 PROGRESSED (第一次住院)。此外,必须在随后的访问中确认此进展(对于该患者,在时间 6 状态达到 4.0(比第一次访问的 3.0 高 1 个点)并且该值在后续访问中得到确认,因此确认了进展。)

         PN        time.state.2 STATUS  PROGRESSION
   [1,] 6954010001            0    3.0            0
   [2,] 6954010001            3    3.5            0
   [3,] 6954010001            6    4.0            1
   [4,] 6954010001            9    4.0            0
   [5,] 6954010001           12    4.5            0
   [6,] 6954010001           15    4.5            0

我还希望每个患者的 PROGRESSION 仅在第一次时为 1,并且可能会(对于该患者)在其进展后放弃后续访问。 例如:

         PN        time.state.2 STATUS  PROGRESSION
   [1,] 6954010001            0    3.0            0
   [2,] 6954010001            3    3.5            0
   [3,] 6954010001            6    4.0            1
   [4,] 6954010002            0    6.0            0
   [5,] 6954010002            3    6.0            0

当第一个患者在 PROGRESSION=1 时停止。

【问题讨论】:

标签: r


【解决方案1】:

我相信你想要这样的东西:

#create data
DF <- read.table(text="         PN        time.state.2 STATUS
   [1,] 6954010001            0    3.0
   [2,] 6954010001            3    3.5
   [3,] 6954010001            6    3.5
   [4,] 6954010001            9    3.5
   [5,] 6954010001           12    3.5
   [6,] 6954010002            0    3.0
   [7,] 6954010002            3    3.0
   [8,] 6954010002            6    3.5
   [9,] 6954010002            9    3.5
   [10,] 6954010002          12    3.5",header=TRUE)

#you claim to have a matrix
m <- as.matrix(DF)

#turn the matrix into a data.frame
DF <- as.data.frame(m)
rownames(DF) <- NULL

#use package plyr to split according to patient, 
#apply function, and combine back
library(plyr)
#calculate the cumulative sum of differences in STATUS
#put a 0 in front, since there can be no progress at the first time point
DF <- ddply(DF,.(PN),transform,progress=c(0,cumsum(diff(STATUS))))

print(DF)
#            PN time.state.2 STATUS progress
# 1  6954010001            0    3.0      0.0
# 2  6954010001            3    3.5      0.5
# 3  6954010001            6    3.5      0.5
# 4  6954010001            9    3.5      0.5
# 5  6954010001           12    3.5      0.5
# 6  6954010002            0    3.0      0.0
# 7  6954010002            3    3.0      0.0
# 8  6954010002            6    3.5      0.5
# 9  6954010002            9    3.5      0.5
# 10 6954010002           12    3.5      0.5

澄清后编辑:

DF <- read.table(text="         PN        time.state.2 STATUS
[1,] 6954010001            0    3.0
[2,] 6954010001            3    3.5
[3,] 6954010001            6    4.0
[4,] 6954010001            9    3.5
[5,] 6954010001           12    6.0
[6,] 6954010002            0    3.0
[7,] 6954010002            3    4.0
[8,] 6954010002            6    4.0
[9,] 6954010002            9    6.0
[10,] 6954010002          12    6.0",header=TRUE)

rownames(DF) <- NULL

DF <- ddply(DF,.(PN),transform,progress=(STATUS-STATUS[1])>=1 & 
                                        (c(STATUS[-1],FALSE)-STATUS[1])>=1)

DF <- ddply(DF,.(PN),function(x) {x$progress[x$progress][-1] <- FALSE; x})

#            PN time.state.2 STATUS progress
# 1  6954010001            0    3.0    FALSE
# 2  6954010001            3    3.5    FALSE
# 3  6954010001            6    4.0    FALSE
# 4  6954010001            9    3.5    FALSE
# 5  6954010001           12    6.0    FALSE
# 6  6954010002            0    3.0    FALSE
# 7  6954010002            3    4.0     TRUE
# 8  6954010002            6    4.0    FALSE
# 9  6954010002            9    6.0    FALSE
# 10 6954010002           12    6.0    FALSE

【讨论】:

  • 如果您的数据库很大并且 plyr 解决方案太慢,我可以使用包 data.table 添加解决方案,它更有效,但使用特殊语法,您可能更难掌握。
  • +1 我希望你不介意,但我还是继续使用你的 cumsum 方法做了一个 data.table 解决方案。我还为不同的可能结果提出了另一种解决方案,因为我无法确定 OP 期望什么输出(我认为不能保证它是正确的)。
  • @Ale 加油! Roland 花时间广泛地解决了您的问题,并提出了一个很好的解决方案,可以完全满足您的需求。你真的应该考虑接受这个作为答案(当然没有义务)或详细描述为什么这是不够的。将已回答标记为已接受意味着它不再出现在未回答问题列表中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 2018-05-25
  • 1970-01-01
相关资源
最近更新 更多