我希望在连续组之间setdiff
而不进行循环,如果可能的话,使用数据表方式或应用族的函数。
Dataframe df:
id group
1 L1 1
2 L2 1
3 L1 2
4 L3 2
5 L4 2
6 L3 3
7 L5 3
8 L6 3
9 L1 4
10 L4 4
11 L2 5
我想知道连续组之间有多少新ID。因此,举例来说,如果我们比较第1组和第2组,则会有两个新ID:L3
和L4
,因此它会返回2(不是直接使用setdiff
,而是使用length()
),如果我们比较第2组和第3组,L5
和L6
是新闻ID,那么它返回2,依此类推。
预期结果:
new_id
2
2
2
1
数据:
structure(list(id = structure(c(1L, 2L, 1L, 3L, 4L, 3L, 5L, 6L,
1L, 4L, 2L), .Label = c("L1", "L2", "L3", "L4", "L5", "L6"), class = "factor"),
group = c(1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5)), class = "data.frame", row.names = c(NA,
-11L), .Names = c("id", "group"))
答案 0 :(得分:3)
以下是mapply
的选项:
lst <- with(df, split(id, group))
mapply(function(x, y) length(setdiff(y, x)), head(lst, -1), tail(lst, -1))
#1 2 3 4
#2 2 2 1
答案 1 :(得分:2)
这是data.table
方式merge
。假设原始data.frame
名为dt
:
library(data.table)
setDT(dt)
dt2 <- copy(dt)[, group := group + 1]
merge(
dt, dt2, by = 'group', allow.cartesian = T
)[, .(n = length(setdiff(id.x, id.y))), by = group]
# group n
# 1: 2 2
# 2: 3 2
# 3: 4 2
# 4: 5 1
答案 2 :(得分:1)
L = split(d, d$group) #Split data ('d') by group and create a list
#use lapply to access 'id' for each sub group in the list and obtain setdiff
sapply(2:length(L), function(i)
setNames(length(setdiff(L[[i]][,1], L[[i-1]][,1])),
nm = paste(names(L)[i], names(L)[i-1], sep = "-")))
#2-1 3-2 4-3 5-4
# 2 2 2 1
答案 3 :(得分:1)
您可以使用Reduce
对列表中的成对元素运行比较函数。例如
xx<-Reduce(function(a, b) {
x <- setdiff(b$id, a$id);
list(id=b$id, new=x, newcount=length(x))
}, split(df, df$group),
acc=TRUE)[-1]
然后你可以用
获取新元素的数量sapply(xx, '[[', "newcount")
您可以使用
获取新值sapply(xx, '[[', "new")