2016-10-19 61 views
3

我有三列數據集:今年,市,值看起來像這樣:的R - 記住,是不是NA最新數據,除非只有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 

如果我子集上最高的一年中,我得到其中當年有ISN來港數據。如果我的子集是!is.na(),那麼我將丟失所有隻有的行不適用。

我想特別做的是獲得具有數據的給定城市的最高年份,除非該城市僅有NAs,然後是NA的最高年份。我會怎麼做呢?

+0

你到底想子集?從你的例子來看,你似乎不想爲最高年份設置子集,是否還有另一個變量不在此處顯示? –

+0

啊,否:我想爲城市列設置子集:除了那個城市只有NAs,然後是NA最高的一年,這個城市數據的最高年份。 這是否使它更清晰? – LukasKawerau

回答

3

我們可以使用data.table。將'data.frame'轉換爲'data.table'(setDT(data)),按'城市'分組,我們指定'i'爲降序order索引中的'年份',ifany非NA'值',我們根據第一個非NA'值'的索引或'else'返回Data.table的子集,返回Data.table的子集。

library(data.table) 
setDT(data)[order(-year), if(any(!is.na(value))) 
      .SD[which(!is.na(value))[1L]] else .SD, by = city] 

或者通過@大衛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] 
+0

這真的很棒,謝謝!如果我有一個擁有NA的城市多年(如2010年,法蘭克福,NA,2011年,法蘭克福,北美; 2013年,法蘭克福,美國北部),它會保留所有這些年。我如何只保留這種情況下的最新年份? – LukasKawerau

+5

或者只是'setDT(data)[order(-year),.SD [which.max(!is.na(value))],by = city]' –

+0

@DavidArenburg這非常好。其實,我正在嘗試與'which'類似。正在通話,所以不能專注於它 – akrun

1

一個更詳細,迂迴法使用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) 
0

max_pos(x)返回位置中的x最後一個非NA元件的x或如果不存在非NA元件返回的x的最後位置。 is_max返回一個在最大位置爲TRUE且在其他地方爲FALSE的邏輯。請注意,ave會將其結果強制爲其第一個參數的類型,因此我們使用!!將其重新轉換爲邏輯。最後,我們將這些元素集中在一起。假設輸入按城市年份分類,就像問題中的情況一樣。

注意max_pos通過使用這些事實變得緊湊:

  • seq_along(x) * 0*x0*x是零向量和NAS因此添加它的NAS出seq_along(x)的相應的元件。也就是說,它給出了與replace(seq_along(x), is.na(x), NA)相同的結果,可用於替代它。
  • which.max返回一個零長度的結果,如果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