我是R的新手,并且在使用更高级的过滤功能时遇到了困难。我有一个包含1500行家庭数据的数据框,需要过滤出至少有1个人年龄超过24岁的家庭成员。例如,在下面的示例集中,我只希望保留第3行,4和5。
PersonalID DOB HouseholdID
1 1961-04-15 123
2 2017-01-12 123
3 2000-01-02 122
4 2001-03-05 122
5 1996-08-22 122
最初,我只是过滤以与该年龄段的每个人都获取一个新的数据框,然后使用25岁以下人群的每个HouseholdID再次过滤一次(一次又一次,依此类推...),以检查是否有人否则,该HouseholdID超过24。
每当我一遍又一遍地做同样的事情时,似乎可能有一种使用函数的方法,但是我很难找到一个可行的函数。这是我目前的尝试,但我知道它有很多问题:
UNDER25df <- filter(df, DOB >= "yyyy-mm-dd")
for (UNDER25df$HouseholdID in df) {
if (all(df$DOB >= "yyyy-mm-dd")) {
view(filter(df, HouseholdID == "$HouseholdID"))
}
}
我得到的错误是:
“}”中意外的“}”
但是我很确定我可以将if语句嵌套在R中的for循环中,并且我对括号的位置非常小心,所以我不知道它到底指的是什么。
我不确定的是我是否可以以这种方式遍历数据帧,或者这是否有意义。我读过,矢量化通常对于高级过滤而言可能更好,但是尝试阅读有关它的文档,并且真的看不到如何解决这个问题。有人对我有任何建议或指示吗?
答案 0 :(得分:1)
您不需要为此进行循环。试试
library(lubridate)
library(dplyr)
set.seed(1)
df <- tibble(DOB = Sys.Date() - sample(3000:12000, 6),
personalID = 1:6,
HouseholdID = c(1,1,2,2,2,3))
df$DOB
# grab householdID from all persons that are at least 24
oldies <- df[(lubridate::today() - lubridate::ymd(df$DOB)) > years(24),
"HouseholdID", TRUE]
# base R way
oldies <- df[as.Date(df$DOB) > as.Date("1993-2-10"),
"HouseholdID", TRUE]
# household members in a household with someone 24 or older
df %>%
filter(HouseholdID %in% oldies)
# household members in a household with noone 24 or older
df %>%
filter(!(HouseholdID %in% oldies))
答案 1 :(得分:0)
我不确定您是否要选择所有人都在24岁以上或至少一个人在24岁以上的家庭。无论如何,您可以将subset
与ave
subset(df, ave(as.integer(format(Sys.Date(), "%Y")) -
as.integer(format(DOB, "%Y")) >= 24, HouseholdID, FUN = any))
这将选择至少一个人在24岁以上的家庭。如果要选择所有人在24岁以上的家庭,请使用all
代替any
中的FUN
。
类似地,使用dplyr
,我们可以使用
library(dplyr)
df %>%
group_by(HouseholdID) %>%
filter(any(as.integer(format(Sys.Date(), "%Y")) -
as.integer(format(DOB, "%Y")) >= 24))
答案 2 :(得分:0)
我不确定您是否要按ID对行进行分组,以确保所有用户均小于或等于24岁。如果是这样,那么也许您可以尝试下面的代码
library(lubridate)
dfout <- subset(df, ave(floor(time_length(Sys.Date()-as.Date(DOB),"years"))<=24, HouseholdID, FUN = all))
for
循环来制作,那么下面是一个示例dfout <- data.frame()
for (id in unique(df$HouseholdID)) {
subdf <- subset(df,HouseholdID == id)
if (with(subdf, all(floor(time_length(Sys.Date()-as.Date(DOB),"years"))<=24))) {
dfout <- rbind(dfout,subdf)
}
}
以上两种方法都可以将结果显示为
> dfout
PersonalID DOB HouseholdID
3 3 2000-01-02 122
4 4 2001-03-05 122
5 5 1996-08-22 122
数据
df <- structure(list(PersonalID = 1:5, DOB = c("1961-04-15", "2017-01-12",
"2000-01-02", "2001-03-05", "1996-08-22"), HouseholdID = c(123L,
123L, 122L, 122L, 122L)), class = "data.frame", row.names = c(NA,
-5L))