基于R中逻辑关系的数据拆分
Data Split based on a logical relationship in R
我有一个包含历史数据的数据集,我想将它分成两组:
- 我至少连续两年有数据的一组ID。
- 它是补充,即我从他们那里获得一年或多年数据但在非连续年份的 ID 集。
例如,我们取数据集A:
A =
ID Year X Y
1 2010 2 3
1 2012 4 0
2 2011 4 3
2 2012 2 2
3 2010 3 1
3 2012 2 1
3 2013 0 3
我要买B套:
B =
ID Year X Y
2 2011 4 3
2 2012 2 2
3 2012 2 1
3 2013 0 3
B'=
ID Year X Y
1 2010 2 3
1 2012 4 0
3 2010 3 1
注意ID 3在B
和B'
中都有显示,因为它有连续年份和单一年份的记录。
我不必在 R 中执行此操作,我也可以使用 Python。任何帮助将不胜感激。
在dplyr
,
library(dplyr)
df %>% group_by(ID) %>% filter(Year %in% c(Year - 1, Year + 1))
# Source: local data frame [4 x 4]
# Groups: ID [2]
#
# ID Year X Y
# (int) (int) (int) (int)
# 1 2 2011 4 3
# 2 2 2012 2 2
# 3 3 2012 2 1
# 4 3 2013 0 3
和
df %>% group_by(ID) %>% filter(!Year %in% c(Year - 1, Year + 1))
# Source: local data frame [3 x 4]
# Groups: ID [2]
#
# ID Year X Y
# (int) (int) (int) (int)
# 1 1 2010 2 3
# 2 1 2012 4 0
# 3 3 2010 3 1
这个想法很简单:group_by(ID)
分别计算每个 ID
,然后 filter
只计算 Year
值小一或一个比该组的所有 Year
值大的值。加一个!
,反逻辑,得到不满足条件的行。
你可以试试用 base R diff
在 Year
列中查找具有 1 年差异的行的索引,获取下一行的索引并对它们进行子集化。
df[sort(c(which(diff(df$Year) == 1),
which(diff(df$Year) == 1) + 1)), ]
# ID Year X Y
#3 2 2011 4 3
#4 2 2012 2 2
#6 3 2012 2 1
#7 3 2013 0 3
和
获取不属于第一个子集的所有行
df[!1:nrow(df) %in% c(which(diff(df$Year) == 1),
which(diff(df$Year) == 1) + 1), ]
# ID Year X Y
#1 1 2010 2 3
#2 1 2012 4 0
#5 3 2010 3 1
和data.table
library(data.table)
setDT(A)[, .SD[Year %in% c(Year-1, Year+1)] , ID]
# ID Year X Y
#1: 2 2011 4 3
#2: 2 2012 2 2
#3: 3 2012 2 1
#4: 3 2013 0 3
或者
setDT(A)[, .SD[!Year %in% c(Year-1, Year+1)] , ID]
# ID Year X Y
#1: 1 2010 2 3
#2: 1 2012 4 0
#3: 3 2010 3 1
对于这两种情况。
另一种选择是
setDT(A)[A[, {i1 <- .I[(Year - shift(Year, fill= Year[1]))==1]
c(i1-1,i1) }, ID]$V1]
我有一个包含历史数据的数据集,我想将它分成两组:
- 我至少连续两年有数据的一组ID。
- 它是补充,即我从他们那里获得一年或多年数据但在非连续年份的 ID 集。
例如,我们取数据集A:
A =
ID Year X Y
1 2010 2 3
1 2012 4 0
2 2011 4 3
2 2012 2 2
3 2010 3 1
3 2012 2 1
3 2013 0 3
我要买B套:
B =
ID Year X Y
2 2011 4 3
2 2012 2 2
3 2012 2 1
3 2013 0 3
B'=
ID Year X Y
1 2010 2 3
1 2012 4 0
3 2010 3 1
注意ID 3在B
和B'
中都有显示,因为它有连续年份和单一年份的记录。
我不必在 R 中执行此操作,我也可以使用 Python。任何帮助将不胜感激。
在dplyr
,
library(dplyr)
df %>% group_by(ID) %>% filter(Year %in% c(Year - 1, Year + 1))
# Source: local data frame [4 x 4]
# Groups: ID [2]
#
# ID Year X Y
# (int) (int) (int) (int)
# 1 2 2011 4 3
# 2 2 2012 2 2
# 3 3 2012 2 1
# 4 3 2013 0 3
和
df %>% group_by(ID) %>% filter(!Year %in% c(Year - 1, Year + 1))
# Source: local data frame [3 x 4]
# Groups: ID [2]
#
# ID Year X Y
# (int) (int) (int) (int)
# 1 1 2010 2 3
# 2 1 2012 4 0
# 3 3 2010 3 1
这个想法很简单:group_by(ID)
分别计算每个 ID
,然后 filter
只计算 Year
值小一或一个比该组的所有 Year
值大的值。加一个!
,反逻辑,得到不满足条件的行。
你可以试试用 base R diff
在 Year
列中查找具有 1 年差异的行的索引,获取下一行的索引并对它们进行子集化。
df[sort(c(which(diff(df$Year) == 1),
which(diff(df$Year) == 1) + 1)), ]
# ID Year X Y
#3 2 2011 4 3
#4 2 2012 2 2
#6 3 2012 2 1
#7 3 2013 0 3
和
获取不属于第一个子集的所有行
df[!1:nrow(df) %in% c(which(diff(df$Year) == 1),
which(diff(df$Year) == 1) + 1), ]
# ID Year X Y
#1 1 2010 2 3
#2 1 2012 4 0
#5 3 2010 3 1
和data.table
library(data.table)
setDT(A)[, .SD[Year %in% c(Year-1, Year+1)] , ID]
# ID Year X Y
#1: 2 2011 4 3
#2: 2 2012 2 2
#3: 3 2012 2 1
#4: 3 2013 0 3
或者
setDT(A)[, .SD[!Year %in% c(Year-1, Year+1)] , ID]
# ID Year X Y
#1: 1 2010 2 3
#2: 1 2012 4 0
#3: 3 2010 3 1
对于这两种情况。
另一种选择是
setDT(A)[A[, {i1 <- .I[(Year - shift(Year, fill= Year[1]))==1]
c(i1-1,i1) }, ID]$V1]