簡體   English   中英

dplyr按變量等級崩潰,但忽略NA

[英]dplyr collapse by rank of variable but ignore NA

我正為數據崩潰而苦苦掙扎。

基本上,我的數據由每年包含多個觀察值的多個指標組成。 我想將其轉換為每個國家/地區每個指標的一項觀察。

我有一個等級指示器,它指定必須選擇觀察序列的序列。

基本上,必須選擇具有第一個等級的觀察值(因此用1代替2),只要該等級的值不是NA。

另一個問題:我的數據集中的年份會隨時間變化,因此有一種方法可以使代碼具有動態性,即它將代碼應用於1990年到2025年之間的所有列名(如果存在)?

df <- data.frame(country.code = c(1,1,1,1,1,1,1,1,1,1,1,1), 
                        id = as.factor(c("GDP", "GDP", "GDP", "GDP", "CA", "CA", "CA", "GR", "GR", "GR", "GR", "GR")), 
                       `1999` = c(NA,NA,NA, 1000,NA,NA, 100,NA,NA, NA,NA,22), 
                       `2000` = c(NA,NA,1, 2,NA,1, 2,NA,1000, 12,13,2), 
                       `2001` = c(3,100,1, 3,100,20, 1,1,44, 65,NA,NA),
                       rank = c(1, 2 , 3 , 4 , 1, 2, 3, 1, 3, 2, 4, 5))

結果應為以下數據集:

    result <- data.frame(country.code = c(1, 1, 1), 
                         id = as.factor(c("GDP", "CA", "GR")),
                         `1999`= c(1000, 100, 22),
                         `2000`= c(1, 1, 12),
                         `2001`= c(3, 100, 1))

我嘗試了以下解決方案(但由於數據中不存在NA,因此該方法不起作用,因此我必須指定每列:

    test <- df %>% group_by(Country.Code, Indicator.Code) %>% 
                summarise(test1999 = `1999`[which.min(rank))

我看不到如何解釋R來省略1999列中NA的情況。

我們可以對一列使用非空值的最小秩進行子集化,例如x[rank==min(rank[!is.na(x)])]

另一個問題:我的數據集中的年份隨時間而變化,....

使用summarise_atvarsmatches可被用於選擇任何列名與4位使用正則表達式,即1990至2025年[0-9]{4}這意味着搜索一個數字“0-9”重復正好是4次)並通過funs將上述過程應用於他們

librar(dplyr)    
df %>% group_by(country.code,id) %>% 
       summarise(`1999` = `1999`[rank==ifelse(all(is.na(`1999`)),1, min(rank[!is.na(`1999`)]))])

df %>% group_by(country.code,id) %>% 
       summarise_at(vars(matches("[0-9]{4}")),funs(.[rank==ifelse(all(is.na(.)), 1, min(rank[!is.na(.)]))]))

 # A tibble: 3 x 5
 # Groups:   country.code [?]
  country.code id    `1999` `2000` `2001`
         <dbl> <fct>  <dbl>  <dbl>  <dbl>
1            1 CA       100      1    100
2            1 GDP     1000      1      3
3            1 GR        22     12      1

下面是一個選項tidyr::fill更換NA第一非小號NA值后,我們arrange d由數據idrank 這可能不是最有效的方法,因為我們先gather然后再spread數據。

library(tidyverse)
df %>% 
  arrange(id, rank) %>% 
  gather(key, value, X1999:X2001) %>% 
  tidyr::fill(value, .direction = "up") %>% 
  spread(key, value) %>% 
  group_by(id) %>% 
  slice(1) %>% 
  ungroup()
# A tibble: 3 x 6
#  country.code id     rank X1999 X2000 X2001
#         <dbl> <fct> <dbl> <dbl> <dbl> <dbl>
#1            1 CA        1   100     1   100
#2            1 GDP       1  1000     1     3
#3            1 GR        1    22    12     1

注:列名不是19992000等,大概在您的數據。 但這很容易采用。

您可以將數據框更改為長格式,刪除na,選擇與最小等級相對應的值,然后再擴展回寬格式

 library(tidyr)
  test <- df %>%
  gather("Year", "Value", X1999:X2001) %>%
  filter(!is.na(Value))%>%
  group_by(country.code, id, Year) %>% 
  arrange(rank)%>%
  summarise(first(Value)) %>%
  spread(Year, `first(Value)`)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM