簡體   English   中英

使用 tidyverse 和管道如何分配固定行

[英]Using tidyverse and pipes how do I assign fixed rows

鑒於此數據框

X1          X2   
2001        NA
abc         10
def         12
xo          13
2002        NA
abc         10
efd         22
dd          23
2005        NA
a           30

所有年份在 X2 中都有 NA。 我的目標是讓這個數據框成為

X1          X2        Date
abc         10        2001
def         12        2001
xo          13        2001
abc         10        2002
efd         22        2002
dd          23        2002
a           30        2005

也就是說,年份變成了它們自己的列,而 NA 已被刪除

我試過的

a = read_csv("given.csv")
a %>% mutate(Date = ifelse(is.na(X2), X1, NA)) 

這會將第一個數據幀變為

X1          X2      Date
2001        NA      2001
abc         10      NA
def         12      NA
xo          13      NA
2002        NA      2002
abc         10      NA
efd         22      NA
dd          23      NA
2005        NA      2005
a           30      NA

我不確定如何將日期列的 NA 替換為每年的上限值。 在那之后,我想我可以直接 drop_na 並且它就像我想要它一樣

我們可以根據 'X1' 中僅數字元素( \\\\d+ )的出現創建一個分組列,獲取累積和,創建 'Date' 作為 'X1' 的first元素, ungroup並刪除 NA 行

library(dplyr)
library(stringr)
a %>%
    group_by(grp = cumsum(str_detect(X1, '^\\d+$'))) %>% 
    mutate(Date = first(X1)) %>%
    ungroup %>% 
    select(-grp) %>%
    na.omit
# A tibble: 7 x 3
#  X1       X2 Date 
#  <chr> <int> <chr>
#1 abc      10 2001 
#2 def      12 2001 
#3 xo       13 2001 
#4 abc      10 2002 
#5 efd      22 2002 
#6 dd       23 2002 
#7 a        30 2005 

或者在zoo使用data.table

library(data.table)
library(zoo)
na.omit(setDT(a)[, Date := na.locf(fifelse(is.na(X2), X1, NA_character_))])

數據

a <- structure(list(X1 = c("2001", "abc", "def", "xo", "2002", "abc", 
"efd", "dd", "2005", "a"), X2 = c(NA, 10L, 12L, 13L, NA, 10L, 
22L, 23L, NA, 30L)), class = "data.frame", row.names = c(NA, 
-10L))

另外一個選項:

library(dplyr)
library(zoo)

a %>% 
  mutate(Date = na.locf(case_when(is.na(X2) ~ X1))) %>%
  na.omit

輸出:

    X1 X2 Date
2  abc 10 2001
3  def 12 2001
4   xo 13 2001
6  abc 10 2002
7  efd 22 2002
8   dd 23 2002
10   a 30 2005

如果您想重置行號,只需使用filter(!is.na(X2))而不是na.omit

PS 您當然可以只加載tidyverse並執行以下操作:

library(tidyverse)

a %>% 
  mutate(Date = case_when(is.na(X2) ~ X1)) %>%
  fill(Date) %>%
  drop_na

.. 但是請注意,與zoona.locf函數相比, fill非常慢。

暫無
暫無

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

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