na.locf(动物园)的替代数字
Alternative to na.locf (zoo) for numbers
我目前有一个相当复杂的数据集,但我试图将其分解并希望手头的问题足够复杂。
我的数据如下所示:
df <- data.frame(c(1,1,1,1,2,2,2,3,3,3), c(3,3,NA,5,0,0,0,7,4,7),
c(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE,
TRUE, FALSE))
colnames(df) <- c("ID", "Number", "Status")
> df
ID Number Status
1 1 3 TRUE
2 1 3 TRUE
3 1 NA TRUE
4 1 5 FALSE
5 2 0 FALSE
6 2 0 FALSE
7 2 0 FALSE
8 3 7 FALSE
9 3 4 TRUE
10 3 7 FALSE
我正在依次查看每个 ID(使用 dplyr group_by)。每当观察的状态为 TRUE 时,我想用状态为 FALSE 的后续数字替换 "Number"。对于 ID = 1,这将意味着所有 4 个观察值的数字为 5。
我找到了解决方法,但我确信一定有更简单的解决方案(使用替换?)。这就是我的处理方式:
library(dplyr)
library(zoo)
# Setting up a new variable that replaces all "unwanted
# numbers by NA
df$newNumber <- NA
df$newNumber[df$Status == FALSE] <- df$Number[df$Status == FALSE]
# Using the zoo function na.locf to replace the Gas
df <- df %>%
group_by(ID) %>%
mutate(Number2 = ifelse(any(Status == TRUE), na.locf(newNumber,
fromLast = TRUE), Number2))
> df
# A tibble: 10 x 5
# Groups: ID [3]
ID Number Status newNumber Number2
<dbl> <dbl> <lgl> <dbl> <dbl>
1 1 3 TRUE NA 5
2 1 3 TRUE NA 5
3 1 NA TRUE NA 5
4 1 5 FALSE 5 5
5 2 0 FALSE 0 0
6 2 0 FALSE 0 0
7 2 0 FALSE 0 0
8 3 7 FALSE 7 7
9 3 4 TRUE NA 7
10 3 7 FALSE 7 7
非常感谢您!
你可以这样做:
library(zoo)
df$Number[df$Status==TRUE] <- NA #replace Number with NA for all Status = TRUE
df$Number <- na.locf(df$Number, fromLast = TRUE)
ID Number Status
1 1 5 TRUE
2 1 5 TRUE
3 1 5 TRUE
4 1 5 FALSE
5 2 0 FALSE
6 2 0 FALSE
7 2 0 FALSE
8 3 7 FALSE
9 3 7 TRUE
10 3 7 FALSE
Data.table解决方案
library(data.table)
setDT(df)
df[Status==TRUE, Number:=NA_real_]
df[,Number:=na.locf(Number, fromLast=TRUE, na.rm = FALSE)]
tidyr::fill
与 zoo::na.locf
.
的工作方式大致相同
library("tidyverse")
df <- data.frame(c(1,1,1,1,2,2,2,3,3,3), c(3,3,NA,5,0,0,0,7,4,7),
c(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE,
TRUE, FALSE))
colnames(df) <- c("ID", "Number", "Status")
df %>%
mutate(Number2 = if_else(Status, NA_real_, Number)) %>%
group_by(ID) %>%
fill(Number2, .direction = "up")
#> # A tibble: 10 x 4
#> # Groups: ID [3]
#> ID Number Status Number2
#> <dbl> <dbl> <lgl> <dbl>
#> 1 1 3 TRUE 5
#> 2 1 3 TRUE 5
#> 3 1 NA TRUE 5
#> 4 1 5 FALSE 5
#> 5 2 0 FALSE 0
#> 6 2 0 FALSE 0
#> 7 2 0 FALSE 0
#> 8 3 7 FALSE 7
#> 9 3 4 TRUE 7
#> 10 3 7 FALSE 7
由 reprex package (v0.2.1)
于 2019-03-18 创建
我目前有一个相当复杂的数据集,但我试图将其分解并希望手头的问题足够复杂。
我的数据如下所示:
df <- data.frame(c(1,1,1,1,2,2,2,3,3,3), c(3,3,NA,5,0,0,0,7,4,7),
c(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE,
TRUE, FALSE))
colnames(df) <- c("ID", "Number", "Status")
> df
ID Number Status
1 1 3 TRUE
2 1 3 TRUE
3 1 NA TRUE
4 1 5 FALSE
5 2 0 FALSE
6 2 0 FALSE
7 2 0 FALSE
8 3 7 FALSE
9 3 4 TRUE
10 3 7 FALSE
我正在依次查看每个 ID(使用 dplyr group_by)。每当观察的状态为 TRUE 时,我想用状态为 FALSE 的后续数字替换 "Number"。对于 ID = 1,这将意味着所有 4 个观察值的数字为 5。
我找到了解决方法,但我确信一定有更简单的解决方案(使用替换?)。这就是我的处理方式:
library(dplyr)
library(zoo)
# Setting up a new variable that replaces all "unwanted
# numbers by NA
df$newNumber <- NA
df$newNumber[df$Status == FALSE] <- df$Number[df$Status == FALSE]
# Using the zoo function na.locf to replace the Gas
df <- df %>%
group_by(ID) %>%
mutate(Number2 = ifelse(any(Status == TRUE), na.locf(newNumber,
fromLast = TRUE), Number2))
> df
# A tibble: 10 x 5
# Groups: ID [3]
ID Number Status newNumber Number2
<dbl> <dbl> <lgl> <dbl> <dbl>
1 1 3 TRUE NA 5
2 1 3 TRUE NA 5
3 1 NA TRUE NA 5
4 1 5 FALSE 5 5
5 2 0 FALSE 0 0
6 2 0 FALSE 0 0
7 2 0 FALSE 0 0
8 3 7 FALSE 7 7
9 3 4 TRUE NA 7
10 3 7 FALSE 7 7
非常感谢您!
你可以这样做:
library(zoo)
df$Number[df$Status==TRUE] <- NA #replace Number with NA for all Status = TRUE
df$Number <- na.locf(df$Number, fromLast = TRUE)
ID Number Status
1 1 5 TRUE
2 1 5 TRUE
3 1 5 TRUE
4 1 5 FALSE
5 2 0 FALSE
6 2 0 FALSE
7 2 0 FALSE
8 3 7 FALSE
9 3 7 TRUE
10 3 7 FALSE
Data.table解决方案
library(data.table)
setDT(df)
df[Status==TRUE, Number:=NA_real_]
df[,Number:=na.locf(Number, fromLast=TRUE, na.rm = FALSE)]
tidyr::fill
与 zoo::na.locf
.
library("tidyverse")
df <- data.frame(c(1,1,1,1,2,2,2,3,3,3), c(3,3,NA,5,0,0,0,7,4,7),
c(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE,
TRUE, FALSE))
colnames(df) <- c("ID", "Number", "Status")
df %>%
mutate(Number2 = if_else(Status, NA_real_, Number)) %>%
group_by(ID) %>%
fill(Number2, .direction = "up")
#> # A tibble: 10 x 4
#> # Groups: ID [3]
#> ID Number Status Number2
#> <dbl> <dbl> <lgl> <dbl>
#> 1 1 3 TRUE 5
#> 2 1 3 TRUE 5
#> 3 1 NA TRUE 5
#> 4 1 5 FALSE 5
#> 5 2 0 FALSE 0
#> 6 2 0 FALSE 0
#> 7 2 0 FALSE 0
#> 8 3 7 FALSE 7
#> 9 3 4 TRUE 7
#> 10 3 7 FALSE 7
由 reprex package (v0.2.1)
于 2019-03-18 创建