![](/img/trans.png)
[英]Delete rows from a data frame in R based on column values in another data frame
[英]R: How to delete rows of a data frame based on the values of a given column
我有100个模拟数据集,例如下面显示一个数据集
pid time status
1 2 1
1 6 0
1 4 1
2 3 0
2 1 1
2 7 1
3 8 1
3 11 1
3 2 0
pid表示患者编号。 这表明每个患者在“时间和状态”列上都有三个记录。 我想编写R代码以删除状态为0的任何行(如果该行不是给定患者的第一次观察的记录),并保留状态为0的行(如果它表示第一次观察),而其余状态为1的行将在此之后该患者的0被删除。 输出应该看起来像
pid time status
1 2 1
1 4 1
2 3 0
3 8 1
3 11 1
由于有100个模拟数据集,因此对于所有数据,状态栏中0和1的位置都不相同。 有人可以提供能够执行此任务的R代码吗? 先感谢您。
dplyr
软件包可以提供帮助。 我在您的数据示例中添加了一条记录,以为pid包含多个0值。
按pid分组,并使用函数first
您可以保留status的第一个值。 由于该组,因此将为每个pid保留所有记录。 然后,如果第一条记录为0且row_number()= 1,以防万一有更多的记录为0(请参见pid 4),或者如果第一条记录的状态为1,并保留所有状态为1的记录,则仅进行过滤。
df %>%
group_by(pid) %>%
filter((first(status) == 0 & row_number() == 1) | (first(status) == 1 & status == 1))
# A tibble: 6 x 3
# Groups: pid [4]
pid time status
<int> <int> <int>
1 1 2 1
2 1 4 1
3 2 3 0
4 3 8 1
5 3 11 1
6 4 3 0
数据:
df <-
structure(
list(
pid = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L),
time = c(2L, 6L, 4L, 3L, 1L, 7L, 8L, 11L, 2L, 3L, 6L, 8L),
status = c(1L, 0L, 1L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 1L, 0L)
),
.Names = c("pid", "time", "status"),
class = "data.frame",
row.names = c(NA,-12L)
)
这个问题在https://stackoverflow.com上更合适。
这是使用tapply()
的尝试tapply()
有点冗长):
dat <- structure(list(pid = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L),
time = c(2L, 6L, 4L, 3L, 1L, 7L, 8L, 11L, 2L),
status = c(1L, 0L, 1L, 0L, 1L, 1L, 1L, 1L, 0L)),
.Names = c("pid", "time", "status"), class = "data.frame",
row.names = c(NA, -9L))
ind <- unlist(tapply(dat$status, dat$pid, function(x) {
# browser()
y <- (rep(FALSE, length(x)))
if (x[1] == 1) {
y[x != 0] <- TRUE
} else {
y[1] <- TRUE
}
y
}))
dat[ind, ]
#> pid time status
#> 1 1 2 1
#> 3 1 4 1
#> 4 2 3 0
#> 7 3 8 1
#> 8 3 11 1
ind
是TRUE
和FALSE
的向量,它们将指示是否应根据您的规则保留一行dat
。
我使用tapply(X, INDEX, FUN)
将函数应用于向量的子集(此处X = dat$status
),该子集由分组因子定义(此处INDEX = dat$pid
)。 在这里,我使用了一个匿名函数(即FUN = function(x){}
)对X
每个子集进行操作。 特别是,我首先将y
定义为FALSE
的向量,稍后再返回。 如果子组的第一个状态为1,则将所有非零元素(即y[x != 0]
)转换为TRUE
。 否则,我仅将第一个元素(即y[1]
)转换为TRUE
。
您可以取消注释browser()
语句,并在控制台上输入n
(表示下一个)或x
或y
(以查看其含义)来查看函数的作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.