data.frame中的子集特定日期(年和月)
这里是我的data.frame:data.frame中的子集特定日期(年和月),r,dataframe,subset,lubridate,R,Dataframe,Subset,Lubridate,这里是我的data.frame: df = read.table(text = 'ID Date 1 1975-01-01 2 1980-02-01 3 1985-05-01 4 1990-07-01 5 1990-08-01 6 1993-01-01 7 1993-09-01', header = TRUE) 我需要通过选择特定日期(年和月)从中创建一个子集 我感兴趣的日期是: dates = c('1980-02',
df = read.table(text = 'ID Date
1 1975-01-01
2 1980-02-01
3 1985-05-01
4 1990-07-01
5 1990-08-01
6 1993-01-01
7 1993-09-01', header = TRUE)
我需要通过选择特定日期(年和月)从中创建一个子集
我感兴趣的日期是:
dates = c('1980-02', '1990-07', '1993-09')
因此,我的输出应该是:
ID Date
2 1980-02-01
4 1990-07-01
7 1993-09-01
是否有可能编写一个独特的代码,从df
和dates
开始,而不在代码中手动添加日期
谢谢
####更新
如果我在同一个月内在df
内得到多个观察结果,比如:
df2 = read.table(text = 'ID Date
1 1975-01-01
2 1980-02-01
9 1980-02-01
3 1985-05-01
4 1990-07-01
12 1990-07-01
16 1990-07-01
5 1990-08-01
6 1993-01-01
7 1993-09-01
67 1993-09-01', header = TRUE)
新产出:
ID Date
2 1980-02-01
9 1980-02-01
4 1990-07-01
12 1990-07-01
16 1990-07-01
7 1993-09-01
67 1993-09-01
谢谢根据您共享的数据,
Date
列的类别为factor。我们将它们转换为Date
类,提取月份和年份部分,并将其与dates
向量匹配,以从df
中获得匹配的行号
df[match(dates, format(as.Date(df$Date), "%Y-%m")), ]
# ID Date
#2 2 1980-02-01
#4 4 1990-07-01
#7 7 1993-09-01
根据更新的问题,如果我们有多个日期要匹配,我们可以在%中使用%这将为您提供所需的输出
df2[format(as.Date(df2$Date), "%Y-%m") %in% dates, ]
# ID Date
#2 2 1980-02-01
#3 9 1980-02-01
#5 4 1990-07-01
#6 12 1990-07-01
#7 16 1990-07-01
#10 7 1993-09-01
#11 67 1993-09-01
根据您共享的数据,Date
列的类别为factor。我们将它们转换为Date
类,提取月份和年份部分,并将其与dates
向量匹配,以从df
中获得匹配的行号
df[match(dates, format(as.Date(df$Date), "%Y-%m")), ]
# ID Date
#2 2 1980-02-01
#4 4 1990-07-01
#7 7 1993-09-01
根据更新的问题,如果我们有多个日期要匹配,我们可以在%
中使用%这将为您提供所需的输出
df2[format(as.Date(df2$Date), "%Y-%m") %in% dates, ]
# ID Date
#2 2 1980-02-01
#3 9 1980-02-01
#5 4 1990-07-01
#6 12 1990-07-01
#7 16 1990-07-01
#10 7 1993-09-01
#11 67 1993-09-01
试一试
试一试
正如@eipi10在评论中指出的那样:
df[df$Date %in% as.Date(paste0(dates,"-01")), ]
这对我更新的问题很有效
正如@eipi10在评论中指出的那样,谢谢你:
df[df$Date %in% as.Date(paste0(dates,"-01")), ]
这对我更新的问题很有效
谢谢以下是一些解决方案。它们(i)处理任何日期,而不仅仅是一个月的第一个日期,(ii)在输出中保留df2
的顺序,(iii)紧凑,即每行一行,不需要多次提及df2
1)substr这不使用包
subset(df2, substr(Date, 1, 7) %in% dates)
给予:
ID Date
2 2 1980-02-01
3 9 1980-02-01
5 4 1990-07-01
6 12 1990-07-01
7 16 1990-07-01
10 7 1993-09-01
11 67 1993-09-01
2)zoo::as.yearmon另一种可能是将日期和日期转换为“yearmon”
类,得到相同的结果。这段代码稍微好一点,但确实需要一个包
library(zoo)
subset(df2, as.yearmon(Date) %in% as.yearmon(dates))
这里有一些解决方案。它们(i)处理任何日期,而不仅仅是一个月的第一个日期,(ii)在输出中保留df2
的顺序,(iii)紧凑,即每行一行,不需要多次提及df2
1)substr这不使用包
subset(df2, substr(Date, 1, 7) %in% dates)
给予:
ID Date
2 2 1980-02-01
3 9 1980-02-01
5 4 1990-07-01
6 12 1990-07-01
7 16 1990-07-01
10 7 1993-09-01
11 67 1993-09-01
2)zoo::as.yearmon另一种可能是将日期和日期转换为“yearmon”
类,得到相同的结果。这段代码稍微好一点,但确实需要一个包
library(zoo)
subset(df2, as.yearmon(Date) %in% as.yearmon(dates))
您的日期格式为字符串,因此使用它们有些困难。一般来说,最好将它们格式化为实际的日期对象。这可以通过使用。这是我要做的。我使用readr包进行自动类型检测,使用purr进行函数式编程
library(pacman)
p_load(lubridate, readr, purrr)
df = read_table(
'ID Date
1 1975-01-01
2 1980-02-01
9 1980-02-01
3 1985-05-01
4 1990-07-01
12 1990-07-01
16 1990-07-01
5 1990-08-01
6 1993-01-01
7 1993-09-01
67 1993-09-01'
)
dates = parse_date_time(c('1980-02', '1990-07', '1993-09'), orders = "Y-m")
#subset
df[year(df$Date) %in% year(dates) & month(df$Date) %in% month(dates), ]
其输出为:
# A tibble: 7 × 2
ID Date
<int> <date>
1 2 1980-02-01
2 9 1980-02-01
3 4 1990-07-01
4 12 1990-07-01
5 16 1990-07-01
6 7 1993-09-01
7 67 1993-09-01
其输出相同:
# A tibble: 7 × 2
ID Date
<int> <date>
1 2 1980-02-01
2 9 1980-02-01
3 4 1990-07-01
4 12 1990-07-01
5 16 1990-07-01
6 7 1993-09-01
7 67 1993-09-01
#一个tible:7×2
身份证日期
1 2 1980-02-01
2 9 1980-02-01
3 4 1990-07-01
4 12 1990-07-01
5 16 1990-07-01
6 7 1993-09-01
7 67 1993-09-01
该函数所做的是在数据框中的每个日期上循环,并在每年/每月的组合上循环。然后检查年份和月份是否匹配该特定组合。如果三个组合中的任何一个匹配(因此为any
),它将返回该行的TRUE
。您的日期被格式化为字符串,因此使用它们有些困难。一般来说,最好将它们格式化为实际的日期对象。这可以通过使用。这是我要做的。我使用readr包进行自动类型检测,使用purr进行函数式编程
library(pacman)
p_load(lubridate, readr, purrr)
df = read_table(
'ID Date
1 1975-01-01
2 1980-02-01
9 1980-02-01
3 1985-05-01
4 1990-07-01
12 1990-07-01
16 1990-07-01
5 1990-08-01
6 1993-01-01
7 1993-09-01
67 1993-09-01'
)
dates = parse_date_time(c('1980-02', '1990-07', '1993-09'), orders = "Y-m")
#subset
df[year(df$Date) %in% year(dates) & month(df$Date) %in% month(dates), ]
其输出为:
# A tibble: 7 × 2
ID Date
<int> <date>
1 2 1980-02-01
2 9 1980-02-01
3 4 1990-07-01
4 12 1990-07-01
5 16 1990-07-01
6 7 1993-09-01
7 67 1993-09-01
其输出相同:
# A tibble: 7 × 2
ID Date
<int> <date>
1 2 1980-02-01
2 9 1980-02-01
3 4 1990-07-01
4 12 1990-07-01
5 16 1990-07-01
6 7 1993-09-01
7 67 1993-09-01
#一个tible:7×2
身份证日期
1 2 1980-02-01
2 9 1980-02-01
3 4 1990-07-01
4 12 1990-07-01
5 16 1990-07-01
6 7 1993-09-01
7 67 1993-09-01
该函数所做的是在数据框中的每个日期上循环,并在每年/每月的组合上循环。然后检查年份和月份是否匹配该特定组合。如果三个组合中的任何一个匹配(因此any
),它将返回该行的TRUE
。因为您的数据看起来是标准化的,所以您可以使用df[substr(df$Date,1,7)%in%dates,]
。但为了安全起见,最好使用正确的日期时间格式。df[df$date%in%as.date(paste0(dates,“-01”),]
。这假设df$Date
已经是日期格式。非常感谢大家!因为您的数据看起来是标准化的,所以您可以在%日期中使用df[substr(df$Date,1,7)%cf
。但为了安全起见,最好使用正确的日期时间格式。df[df$date%in%as.date(paste0(dates,“-01”),]
。这假设df$Date
已经是日期格式。非常感谢大家!嗨,我刚更新了我的问题,你能看一下吗?谢谢,我刚刚更新了我的问题,你能看一下吗?谢谢