R - 保留非 NA 的最新数据,除非只有 NA 可用
R - Keep newest data that is not NA, unless only NA available
我有一个包含三列的数据集:年份、城市、值,如下所示:
year = c(2010, 2013, 2010, 2013, 2013)
city = c("Berlin","Berlin", "Munich", "Munich", "Frankfurt")
value = c(1234, NA, NA, 6372, NA)
data <- data.frame(year, value1, value2)
year city value
1 2010 Berlin 1234
2 2013 Berlin NA
3 2010 Munich NA
4 2013 Munich 6372
5 2013 Frankfurt NA
我想知道如何对其进行子集化,以便只保留可用的最新数据,这样最后我得到的数据如下:
year city value
1 2010 Berlin 1234
2 2013 Munich 6372
3 2013 Frankfurt NA
如果我在最高年份进行子集化,我会在该年份没有数据的地方得到 NA。如果我在 !is.na()
上设置子集,我将丢失所有 only NA 可用的行。
我特别想做的是获取给定城市数据的最高年份,除非该城市只有 NA,然后是具有 NA 的最高年份。我该怎么做?
我们可以使用data.table
。将'data.frame'转换为'data.table'(setDT(data)
),按'city'分组,我们指定'i'为降序order
中的'year' ]索引,if
有any
个非NA'value',我们根据第一个非NA'value'或[=的索引对'Data.table'进行子集18=] return Data.table.
的子集
library(data.table)
setDT(data)[order(-year), if(any(!is.na(value)))
.SD[which(!is.na(value))[1L]] else .SD, by = city]
或者@David Arenburg 提供的紧凑选项,我们从 which.max
获取索引
setDT(data)[order(-year), .SD[which.max(!is.na(value))], by = city]
或使用 .I
进行修改以使其更快
setDT(data)[data[order(-year), .I[which.max(!is.na(value))], by = city]$V1]
使用 dplyr
的更冗长、迂回的方法。它也适用于您有多年 NA
.
的情况
library(dplyr)
data %>%
group_by(city) %>%
mutate(all_na = all(is.na(value)),
remove = ifelse(all_na,
year != max(year),
is.na(value))) %>%
ungroup() %>%
filter(!remove) %>%
select(-all_na, -remove)
max_pos(x)
returns x
的最后一个非 NA 元素在 x
中的位置,或者如果没有非 NA 元素它 returns x
的最后一个位置。 is_max
returns 逻辑,在最大位置为 TRUE,在其他位置为 FALSE。请注意 ave
会将其结果强制为其第一个参数的类型,因此我们使用 !!
将其转回逻辑。最后,我们将这些元素子集化。这假设输入是按城市内的年份排序的,就像问题中的情况一样。
请注意,max_pos
是通过使用以下事实变得紧凑的:
- 在
seq_along(x) * 0*x
中,0*x
是零和 NA 的向量,因此将它添加到 seq_along(x)
的相应元素中。也就是说,它给出的结果与 replace(seq_along(x), is.na(x), NA)
相同,可以用它代替。
which.max
returns 零长度结果,如果 x
是所有 NA 值并且 c(arg1, arg2)[1]
给出与 if (length(arg1) == 0) arg2 else arg1
相同的结果,可用于它的位置。
没有使用包。
max_pos <- function(x) c(which.max(seq_along(x) + 0*x), length(x))[1]
is_max <- function(x) seq_along(x) == max_pos(x)
subset(data, !!ave(value, city, FUN = is_max))
给予:
year city value
1 2010 Berlin 1234
4 2013 Munich 6372
5 2013 Frankfurt NA
我有一个包含三列的数据集:年份、城市、值,如下所示:
year = c(2010, 2013, 2010, 2013, 2013)
city = c("Berlin","Berlin", "Munich", "Munich", "Frankfurt")
value = c(1234, NA, NA, 6372, NA)
data <- data.frame(year, value1, value2)
year city value
1 2010 Berlin 1234
2 2013 Berlin NA
3 2010 Munich NA
4 2013 Munich 6372
5 2013 Frankfurt NA
我想知道如何对其进行子集化,以便只保留可用的最新数据,这样最后我得到的数据如下:
year city value
1 2010 Berlin 1234
2 2013 Munich 6372
3 2013 Frankfurt NA
如果我在最高年份进行子集化,我会在该年份没有数据的地方得到 NA。如果我在 !is.na()
上设置子集,我将丢失所有 only NA 可用的行。
我特别想做的是获取给定城市数据的最高年份,除非该城市只有 NA,然后是具有 NA 的最高年份。我该怎么做?
我们可以使用data.table
。将'data.frame'转换为'data.table'(setDT(data)
),按'city'分组,我们指定'i'为降序order
中的'year' ]索引,if
有any
个非NA'value',我们根据第一个非NA'value'或[=的索引对'Data.table'进行子集18=] return Data.table.
library(data.table)
setDT(data)[order(-year), if(any(!is.na(value)))
.SD[which(!is.na(value))[1L]] else .SD, by = city]
或者@David Arenburg 提供的紧凑选项,我们从 which.max
setDT(data)[order(-year), .SD[which.max(!is.na(value))], by = city]
或使用 .I
进行修改以使其更快
setDT(data)[data[order(-year), .I[which.max(!is.na(value))], by = city]$V1]
使用 dplyr
的更冗长、迂回的方法。它也适用于您有多年 NA
.
library(dplyr)
data %>%
group_by(city) %>%
mutate(all_na = all(is.na(value)),
remove = ifelse(all_na,
year != max(year),
is.na(value))) %>%
ungroup() %>%
filter(!remove) %>%
select(-all_na, -remove)
max_pos(x)
returns x
的最后一个非 NA 元素在 x
中的位置,或者如果没有非 NA 元素它 returns x
的最后一个位置。 is_max
returns 逻辑,在最大位置为 TRUE,在其他位置为 FALSE。请注意 ave
会将其结果强制为其第一个参数的类型,因此我们使用 !!
将其转回逻辑。最后,我们将这些元素子集化。这假设输入是按城市内的年份排序的,就像问题中的情况一样。
请注意,max_pos
是通过使用以下事实变得紧凑的:
- 在
seq_along(x) * 0*x
中,0*x
是零和 NA 的向量,因此将它添加到seq_along(x)
的相应元素中。也就是说,它给出的结果与replace(seq_along(x), is.na(x), NA)
相同,可以用它代替。 which.max
returns 零长度结果,如果x
是所有 NA 值并且c(arg1, arg2)[1]
给出与if (length(arg1) == 0) arg2 else arg1
相同的结果,可用于它的位置。
没有使用包。
max_pos <- function(x) c(which.max(seq_along(x) + 0*x), length(x))[1]
is_max <- function(x) seq_along(x) == max_pos(x)
subset(data, !!ave(value, city, FUN = is_max))
给予:
year city value
1 2010 Berlin 1234
4 2013 Munich 6372
5 2013 Frankfurt NA