繁体   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