我有一个包含三列的数据集:年份,城市,价值,如下所示:
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
如果我是最高年份的子集,我会获得那些年份没有数据的NAs。如果我在!is.na()
上进行了子集,则会丢失所有仅 NA可用的行。
我想要具体做的是获得具有数据的特定城市的最高年份,除非该城市只有NA,然后是NA的最高年份。我该怎么做呢?
答案 0 :(得分:3)
我们可以使用data.table
。转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(data)
),按城市&#39;分组,我们指定&#39; i&#39;作为&#39;年&#39;在降序order
索引中,if
有any
非NA&#39;值&#39;,我们将&#39; Data.table&#39;基于第一个非NA值的索引&#39;或else
返回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]
答案 1 :(得分:1)
使用stdafx.h: No such file or directory
Windows.h: No such file or directory
的更详细,更迂回的方法。它也适用于您有多年dplyr
的情况。
NA
答案 2 :(得分:0)
max_pos(x)
返回x
的最后一个非NA元素的x
中的位置,或者如果没有非NA元素,则返回x
的最后一个位置。 is_max
返回逻辑,该逻辑在最大位置为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
是所有NA值,则{li> x
会返回零长度结果,而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