我有一个表格中的数据:
id source
1 m
1 p
1 l1
1 l1
2 t
2 q
3 p
3 l1
3 n
3 l1
现在对于每个id,我想在源中发生l1时识别l1并在l1之前提取观察值。 例如:对于id 1,l1中的第3个源和之前的观察是p。 所以我的数据应该是这样的:
id source
1 p
3 p
3 n
我如何在R中创建它?
答案 0 :(得分:3)
data.table解决方案
library(data.table)
dd <- data.table(df)
dd[, source[match('l1', source)-1L],by = id]
答案 1 :(得分:1)
可能有更直接的方法,但试试这个:
#get your data
test <- read.table(text="id source
1 m
1 p
1 l1
1 l1
2 t
2 q
3 p
3 l1
3 n
3 l1",header=TRUE)
# do some picking of the cases
result <- do.call(rbind,by(test,test$id,function(x) x[which(x$source=="l1")-1,]))
result <- result[result$source!="l1",]
给出了:
> result
id source
2 1 p
7 3 p
9 3 n
答案 2 :(得分:1)
这是另一个data.table解决方案。我无法从@mnel的早期版本中获得正确答案。
library(data.table)
## Create the test data table:
dt <- data.table(id=c(1,1,1,1,2,2,3,3,3,3),
source1=c("m","p","l1","l1","t","q","p","l1","n","l1"))
dt[,list(id, source1, source0=c(NA,source1[seq_len(.N-1L)]))][source1=="l1"]
## id source1 source0
## 1: 1 l1 p
## 2: 1 l1 l1
## 3: 3 l1 p
## 4: 3 l1 n
这是将一个列source0添加到获取前一行(或第一行的NA)的数据表中。 .N
是一个行号,我正在使用seq_len
来获取上一行号。然后它将结果子集设置为原始source1的值为“l1”。
答案 3 :(得分:0)
这是一个矢量化解决方案,仅使用R基础的简单函数。
如果DF
是输入数据框,则sel
是一个逻辑向量,其TRUE
个组件选择所需的行。由&
符号连接的三个术语选择这些行:
source
列等于“l1”和l1
和id
sel
的长度比DF
中的行数少一个,因此我们使用which
来避免sel
的回收。
is.l1 <- DF$source == "l1"
sel <- is.l1[-1] & !is.l1[-nrow(DF)] & duplicated(DF$id)[-1]
DF[which(sel),]
最后一行的结果是:
id source
2 1 p
7 3 p
9 3 n