提问人:V Fishlock 提问时间:1/25/2023 最后编辑:V Fishlock 更新时间:3/20/2023 访问量:62
在 for 循环中使用 if 条件对数据帧进行子集
Subset a dataframe using if-conditions inside a for loop
问:
我正在尝试使用这种基本结构来解决数据重塑问题;
for(i in 1:5) { # Head of for-loop
if(i < 4) { # First if-condition
if(i %in% seq(2, 10, 2)) { # Second if-condition
print(i) # Some output
}
}
}
免责声明,尽管我在这段代码中讨论的是“日期”,但它们是儒略日期系统,因此它们不是 POSIXct 格式,而是表现为整数。
我想使用值列表(“dates”)在满足 2 个条件的列表“bydates”中查找事例,并将它们写入新的 df。“bydates”有 2275 个观测值,涉及 4 个变量;NatalName、JStart、JEnd、FAM(格式为 chr、num、num、chr)。
对于“日期”中的每个值 (i) 我想评估 JStart 是否< i,以及 JEnd 是否> i,以及是否满足这两个条件以写入格式为 i、NatalNAme、FAM 的列表 df。
这是我的尝试之一,我一直在回想(我也尝试了函数,ifelse 和 if_else,但没有成功)。
lists <- c() # create a blank variable to store the result
for(i in dates)
{if(bydates$Jstart <= i) {
if(JEnd > i) {
lists <- as.df(i, bydates$FAM, bydates$NatalName)
}
}
}
这将返回 “Error in if (bydates$Jstart <= i) { : the condition has length > 1”
我认为这意味着我的“bydates”df 中的多个值符合条件,这是正确的,但这是否意味着我应该循环使用“bydates”?我花了一个多星期的时间研究这个问题,但我仍然被困住了。我也很困惑为什么我没有收到通常报告的“条件长度为 >1,并且只会使用第一个元素”错误。
任何帮助非常感谢。
编辑:根据@Stefan的要求,使用dput的数据片段
> dput(dates[1:4])
c(744, 864, 984, 1224)
> dput(head(bydates))
structure(list(NatalName = c("AAN12", "AAN18", "AAN20", "ABI96",
"ABR12", "ABR17"), Jstart = c(1113, 1178, 1203, 914, 1105, 1175
), JEnd = c(1158, 1180, -23053, 915, -23053, -23053), FAM = c("AA",
"AA", "AA", "AA", "AA", "AA")), row.names = c(NA, -6L), class = c("tbl_df",
"tbl", "data.frame"))
答:
问题是没有矢量化。它旨在用于控制脚本的流程,即如果满足一个条件,则执行 A.换句话说,要求条件返回长度为 1 的逻辑向量,而条件返回长度为 1 >向量,即长度等于数据集中的行数。因此,您会收到一个错误。if
if
bydates$Jstart <= i
虽然有矢量化,但总体上不需要 an。您要实现的是数据集的子集,这可以通过使用例如ifelse
if
bydates[bydates$Jstart <= i & bydates$JEnd > i,]
此外,由于您需要一个数据集列表,您可以考虑使用而不是循环:lapply
for
基于一些虚假示例数据使用(和用于子集)的最小可重现示例可能如下所示:lapply
subset
bydates <- data.frame(
JStart = seq(as.Date("2022-01-03"), as.Date("2022-01-12"), by = "day"),
JEnd = seq(as.Date("2022-01-01"), as.Date("2022-01-10"), by = "day"),
FAM = letters[1:10],
NatalName = LETTERS[1:10]
)
dates <- c(as.Date("2022-01-05"), as.Date("2022-01-10"))
lapply(dates, function(i) {
bydates$i <- i
subset(bydates, JStart >= i & JEnd < i, c(i, FAM, NatalName))
})
#> [[1]]
#> i FAM NatalName
#> 3 2022-01-05 c C
#> 4 2022-01-05 d D
#>
#> [[2]]
#> i FAM NatalName
#> 8 2022-01-10 h H
#> 9 2022-01-10 i I
评论
x[r, vars, drop = drop]
rlang::last_error()
bydates
dates
dput(), e.g. type
dput(dates[1:5])
dput()
在朋友的帮助下,我用咕噜咕噜想出了一个解决方案;
library(purrr)
setdates<-function(y){
bydates %>%
filter(Jstart<= y & JEnd >y) %>%
mutate(Date = y) %>%
select(NatalName, FAM, Date) %>%
arrange(FAM)}
famdat<-map_df(dates, setdates)
我的问题是,在设置处理数据操作的函数之前,我试图集成日期。以防这对其他人有帮助......
评论
if()
if()
if
ifelse()
if