我有一个类似于此的数据框:
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的最后一次观察。
答案 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的规范。