excel - 保留上一年的行
问题描述
我只是想试一试,因为我知道这里有一些聪明的人可能有一个 r 代码。我将无法自己编写代码。
所以我得到了一个数据集,其中包含 2000-01 和 2008-12 之间的名称和年月。看起来像这样:
Name Date
A 2000-01
A 2000-02
A ...
A 2008-12
A 2000-01
B 2000-01
B ...
B 2008-12
C and so on..
可能发生的情况是,对于我的键列中的每个名称,每年都有一个值。这是我能要求的最好的。不幸的是,有些年份在我的关键列中没有价值。在我的数据集中进一步了解仅查看名称 A:
因此,如果我在 2000 年至 2008 年之间的每一年都没有 1 个观察值,并且我想根据下一次观察的年份中的月份从年份和月份中获取对我的键列没有值的行。在这个例子中:
2003-02 对我的 keycolumn 有一个值,而 2002-02 没有,我想从日期 2002-02 和名称 A 中取回该行。简而言之:“根据来自上一年的键列保留上一年的行明年”
有一些简单的方法来编码吗?谢谢 :)
解决方案
没有直接简单的方法来编码您所描述的内容,但当然可以将问题分解为更简单的部分。问题的核心部分如下。给定具有非 NA 值的行的数据框,例如
year month
1 2002 12
2 2005 11
3 2006 01
4 2008 07
对于每一行,检查数据框以查看上一年是否存在;如果是,则返回该行,如果否,则返回上一年和同月的附加行。这是一个可能看起来像的函数
check_ym <- function(y, m, dat) {
if ((y - 1) %in% dat$year) {
return(data.frame(Date = paste(y, m, sep = "-"), stringsAsFactors = FALSE))
} else {
return(data.frame(Date = paste(c(y - 1, y), c(m, m), sep = "-"), stringsAsFactors = FALSE))
}
}
现在,让我们制作一些假数据。
library(dplyr)
library(tidyr)
library(purrr)
# Simulate data
set.seed(123)
x <- data.frame(Date = paste(sample(2000:2008, 4),
sprintf("%02d", sample(1:12, 4, replace = TRUE)),
sep = "-"),
KeyColumn = floor(runif(4, 1, 10)))
d <- data.frame(Date = paste(rep(2000:2008, each = 12),
sprintf("%02d", rep(1:12, times = 9)),
sep = "-")) %>%
left_join(x)
识别非 NA 行:
dd <- d %>%
na.omit() %>%
separate(Date, into = c("year", "month")) %>%
mutate(year = as.numeric(year))
dd
# year month KeyColumn
# 1 2002 12 5
# 2 2005 11 5
# 3 2006 01 5
# 4 2008 07 9
然后,我们运行上面的函数,遍历year
和month
列。这给了我们
out <- map2_df(dd$year, dd$month, .f = check_ym, dat = dd)
out
# Date
# 1 2001-12
# 2 2002-12
# 3 2004-11
# 4 2005-11
# 5 2006-01
# 6 2007-07
# 7 2008-07
最后,我们将其与原始数据结合起来:
inner_join(out, d)
# Joining, by = "Date"
# Date KeyColumn
# 1 2001-12 NA
# 2 2002-12 5
# 3 2004-11 NA
# 4 2005-11 5
# 5 2006-01 5
# 6 2007-07 NA
# 7 2008-07 9
这只是为了一个Name
。我们也可以对许多Name
s 执行此操作。首先创建一些假数据:
# Simulate data
set.seed(123)
d <- map_df(setNames(1:3, LETTERS[1:3]), function(...) {
x <- data.frame(Date = paste(sample(2000:2008, 4),
sprintf("%02d", sample(1:12, 4, replace = TRUE)),
sep = "-"),
KeyColumn = floor(runif(4, 1, 10)))
data.frame(Date = paste(rep(2000:2008, each = 12),
sprintf("%02d", rep(1:12, times = 9)),
sep = "-")) %>%
left_join(x)
}, .id = "Name")
dd <- d %>%
na.omit() %>%
separate(Date, into = c("year", "month")) %>%
mutate(year = as.numeric(year))
dd
# Name year month KeyColumn
# 1 A 2002 12 5
# 2 A 2005 11 5
# 3 A 2006 01 5
# 4 A 2008 07 9
# 5 B 2000 04 6
# 6 B 2004 01 7
# 7 B 2005 12 9
# 8 B 2006 03 9
# 9 B 2000 04 6
# 10 C 2003 12 1
# 11 C 2005 04 7
# 12 C 2006 11 5
# 13 C 2008 02 8
现在,使用split
将数据帧拆分为三个数据帧Name
;对于每个子数据框,我们应用check_ym()
,然后我们将结果组合在一起并将其与原始数据连接:
lapply(split(dd, dd$Name), function(dat) {
map2_df(dat$year, dat$month, .f = check_ym, dat = dat)
}) %>%
bind_rows(.id = "Name") %>%
inner_join(d)
# Joining, by = c("Name", "Date")
# Name Date KeyColumn
# 1 A 2001-12 NA
# 2 A 2002-12 5
# 3 A 2004-11 NA
# 4 A 2005-11 5
# 5 A 2006-01 5
# 6 A 2007-07 NA
# 7 A 2008-07 9
# 8 B 2000-04 6
# 9 B 2003-01 NA
# 10 B 2004-01 7
# 11 B 2005-12 9
# 12 B 2006-03 9
# 13 C 2002-12 NA
# 14 C 2003-12 1
# 15 C 2004-04 NA
# 16 C 2005-04 7
# 17 C 2006-11 5
# 18 C 2007-02 NA
# 19 C 2008-02 8
推荐阅读
- python - 我收到一个错误,说 string return ' ' 但我有一个 0 那里。它不是通过字符串吗?
- spring - 有没有办法通过spring statemachine中的rest api构建状态机?
- arrays - 更新反应钩子中对象列表的元素。将数组绑定到选择控件列表
- python - 在 VS Code 中获取“ModuleNotFoundError: No module named 'Pillow'”
- reactjs - 在第一次 history.push('xxx') 之后,props.history.goBack() 在 iOS 微信浏览器中不起作用
- azure-ad-b2c - Azure B2C 更改密码策略 - 如何避免登录
- azure - 是否可以通过 Microsoft devops 管道来恢复 Microsoft Azure 中 SQL Server 资源中的备份 .bak?
- python - 如何使用 mocker.patch.object() 和 pytest-mock 模拟类实例并为该实例分配属性?
- reactjs - ReactJs/Node 应用和 Flutter 移动应用之间的数据共享
- docker - npm install -g apiconnect 在 Docker 容器 (RHEL8) 中失败