gpt4 book ai didi

r - 在数据框中按组选择所有行(包括第一次出现)

转载 作者:行者123 更新时间:2023-12-04 08:30:09 24 4
gpt4 key购买 nike

我一直在摸索如何做。我正在重新组织一些不平衡的面板数据(堆叠/长格式)。我需要按组(id)保持所有行直到并包括第一次出现的变量(indc = D)值,并且还保留尚未发生的组的行。我希望丢弃的唯一行是每组的行,其中有第二个或更多指示变量值 (indc=D)。我还需要保留数据框中的所有列。

# Data 
id<-factor(c(1,1,1,2,2,2,2,2, 3,3,3,3,3,3,4,4))
time<-c(1,2,3,1,2,3,4,5, 1,2,3,4,5,6, 1,2)
indc<-factor(c("C","C","D","C","C","C","D","D","C","C","C","C","D","D","C","C"))
var1<-sample(seq(1,8.5, by=0.5))
var2<-c(rep(1,8),rep(0,8))

df<-data.frame(id,time,indc,var1,var2)

我的尝试是使用 by 和 match - 问题是它返回最后一个变量作为匹配项和每个组的索引。我坚持如何获得最终解决方案。

attempt<-by(df, df$id, function(x) {match(unique(x$indc=="D"), x$indc=="D")} )

results<-(do.call("rbind", attempt))

想要的结果是 df2 df2<-df[c(1:3,4:7,9:13,15:16),]

如果有人对解决方案有想法,我将不胜感激。

最佳答案

一种选择是使用 dplyr 按“id”分组,然后计算“indc == “D”的行的累积总和。然后检查并过滤该 cumsum <= 1 的所有行。

require(dplyr)
df %>% group_by(id) %>% filter(cumsum(indc == "D") <= 1)
#Source: local data frame [14 x 5]
#Groups: id
#
# id time indc var1 var2
#1 1 1 C 1.5 1
#2 1 2 C 1.0 1
#3 1 3 D 7.0 1
#4 2 1 C 2.5 1
#5 2 2 C 3.5 1
#6 2 3 C 6.5 1
#7 2 4 D 3.0 1
#8 3 1 C 2.0 0
#9 3 2 C 7.5 0
#10 3 3 C 6.0 0
#11 3 4 C 8.0 0
#12 3 5 D 8.5 0
#13 4 1 C 4.0 0
#14 4 2 C 4.5 0

在评论后编辑#1:

感谢@akrun 下面的评论,这里有更多关于如何进行子集化的选项:

选项 1:使用基础 R:

df[with(df, ave(indc=='D', id, FUN=function(x) cumsum(x)<=1)),]

选项 2:使用 data.table:

require(data.table)
setDT(df)[,.SD[cumsum(indc=='D')<=1], by=id]

感谢@akrun


在 OP 评论后编辑#2:

如果出现第一个“D”,然后在同一组中的另一行出现“C”(或其他字母),那么您希望如何删除行并不是 100% 清楚的。如果它发生在第一次“D”出现之后,我的最初答案会保持这样的一行。要更改该行为并在第一次出现“D”后删除所有行,您可以简单地在代码中添加另一个 cumsum,如下所示(对于修改后的数据,如下所示):

df %>% group_by(id2) %>% filter(cumsum(cumsum(indc2 == "D")) <= 1L)
#Source: local data frame [13 x 5]
#Groups: id2
#
# id2 time2 indc2 var1 var2
#1 1 1 C 8.0 1
#2 1 2 C 5.0 1
#3 1 3 D 7.0 1
#4 2 1 C 1.0 1
#5 2 2 C 2.0 1
#6 2 3 D 9.0 1
#7 3 1 C 4.5 0
#8 3 2 C 3.0 0
#9 3 3 C 7.5 0
#10 3 4 C 1.5 0
#11 3 5 D 4.0 0
#12 4 1 C 6.0 0
#13 4 2 C 6.5 0

数据

df <- structure(list(id2 = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L), .Label = c("1", "2",
"3", "4"), class = "factor"), time2 = c(1, 2, 3, 4, 1, 2, 3,
4, 5, 1, 2, 3, 4, 5, 6, 1, 2), indc2 = structure(c(1L, 1L, 2L,
1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L), .Label = c("C",
"D"), class = "factor"), var1 = c(8, 5, 7, 8.5, 1, 2, 9, 3.5,
2.5, 4.5, 3, 7.5, 1.5, 4, 5.5, 6, 6.5), var2 = c(1, 1, 1, 1,
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0)), .Names = c("id2", "time2",
"indc2", "var1", "var2"), row.names = c(NA, -17L), class = "data.frame")

> df
id2 time2 indc2 var1 var2
1 1 1 C 8.0 1
2 1 2 C 5.0 1
3 1 3 D 7.0 1
4 1 4 C 8.5 1 <-- this row will also be removed now
5 2 1 C 1.0 1
6 2 2 C 2.0 1
7 2 3 D 9.0 1
8 2 4 D 3.5 1
9 2 5 D 2.5 0
10 3 1 C 4.5 0
11 3 2 C 3.0 0
12 3 3 C 7.5 0
13 3 4 C 1.5 0
14 3 5 D 4.0 0
15 3 6 D 5.5 0
16 4 1 C 6.0 0
17 4 2 C 6.5 0

关于r - 在数据框中按组选择所有行(包括第一次出现),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26785499/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com