将前一行中与R中最后一行具有相同值的所有行组合在一起

时间:2015-09-24 11:47:08

标签: r

我有一个类似于此的数据框:

ID  Description
1  "Low Blood Sugar, High Temperature"
1  "No Appetite"
2  "Blood Test Taken"
2  "D4556 Applied, No Obvious Reaction"
3  "At Rest"
1  "Lower Temperature, Improving"
1  "Walked 50m"
1  "Sedated"

我想要做的是作为一个数组返回,最后一个患者ID以及之前发生在同一患者身上的所有评论。也就是说,不是之前发生的任何事情。例如,我想返回:

ID  Description
1  "Lower Temperature, Improving, Walked 50m, Sedated"

我可以使用for循环来解决这个问题,但是我有一个很大的数据框,并且想要更高效的东西。我已经使用ddply对不同变量进行了子集化,这就是为什么我只需要最后一次ID的最后一次观察。

5 个答案:

答案 0 :(得分:4)

另一种data.table方法(使用rleid):

library(data.table) #1.9.6
res <- setDT(df)[, list(ID[1L], toString(Description)), by = rleid(ID)]

您可以稍后使用

删除rleid
res[, rleid := NULL]

如果您只想以汇总形式返回上一个ID,则可以执行以下操作:

idx <- df[,rleid(ID)]
df[idx == max(idx), list(ID[1L], toString(Description))]
#   V1                                                V2
#1:  1 Lower Temperature, Improving, Walked 50m, Sedated

答案 1 :(得分:1)

我认为这可能是一个解决方案:

#use rle to get the number of rows for the last id
idrows <- rle(df$ID)$lengths[length(rle(df$ID)$lengths)]
#use rle in the same way to get the actual id value
id     <- rle(df$ID)$values[length(rle(df$ID)$values)]

#combine the above two variables to calculate the needed values
#i.e. the id and the pasted-together descriptions
> data.frame(id = id, Description = paste(df[(nrow(df)-idrows+1):nrow(df), 'Description'], 
                                          collapse=','))

  id                                     Description
1  1 Lower Temperature, Improving,Walked 50m,Sedated

为了使其更清晰,df[(nrow(df)-idrows+1):nrow(df), 'Description']选择所需ID的最后一行,paste将这些描述粘贴在一起。

答案 2 :(得分:1)

首先,我们在列ID中按组创建唯一ID:

df$id <- cumsum(c(1, diff(df$ID)!=0))

  ID                        Description id
1  1  Low Blood Sugar, High Temperature  1
2  1                        No Appetite  1
3  2                   Blood Test Taken  2
4  2 D4556 Applied, No Obvious Reaction  2
5  3                            At Rest  3
6  1       Lower Temperature, Improving  4
7  1                         Walked 50m  4
8  1                            Sedated  4

然后我们选择满足条件的最后一行并创建向量:

c(t(df[df$id==max(df$id),][2]))

输出:

[1] "Lower Temperature, Improving" "Walked 50m" "Sedated"  

答案 3 :(得分:0)

使用data.table,您可以尝试:

require(data.table)
setDT(df)
dt[,list(ID=ID[1],Description=paste(Description,collapse=", ")),
    by=cumsum(c(TRUE,df$ID[2:nrow(df)]!=df$ID[1:(nrow(df)-1)]))][,
    list(ID,Description)]   
#ID                                             Description
#1:  1       Low Blood Sugar, High Temperature, No Appetite
#2:  2 Blood Test Taken, D4556 Applied, No Obvious Reaction
#3:  3                                              At Rest
#4:  1    Lower Temperature, Improving, Walked 50m, Sedated

答案 4 :(得分:0)

虽然这个老问题已经有了一个公认的答案,但我觉得有必要添加另一个使用data.table但与this answer不同的rleid()解决方案:

library(data.table)   # CRAN version 1.10.4 used
setDT(DF)[, .(ID, Description = toString(Description)), by = rleid(ID)][, .SD[.N]]
#   rleid ID                                       Description
#1:     4  1 Lower Temperature, Improving, Walked 50m, Sedated

这将返回有关OP请求的最后一个患者ID的汇总的最后一个条目。

正如在其他答案中已经提到的,可以通过链接rleid删除[, rleid := NULL]

简而言之,我们可以为每个患者ID检索汇总的最后一个条目,稍作修改:

setDT(DF)[, .(Description = toString(Description)), .(ID, rleid(ID))][, .SD[.N], ID]
#   ID rleid                                          Description
#1:  1     4    Lower Temperature, Improving, Walked 50m, Sedated
#2:  2     2 Blood Test Taken, D4556 Applied, No Obvious Reaction
#3:  3     3                                              At Rest

请注意,只要它是第三个未命名的参数,就不需要命名by参数。

数据

library(data.table)
DF <- fread(
  'ID  Description
1  "Low Blood Sugar, High Temperature"
1  "No Appetite"
2  "Blood Test Taken"
2  "D4556 Applied, No Obvious Reaction"
3  "At Rest"
1  "Lower Temperature, Improving"
1  "Walked 50m"
1  "Sedated"'
, data.table = FALSE)

请注意,参数data.table = FALSE指示fread()返回data.frame以符合OP的规范。