使用 dplyr 在时间序列数据中用 NA 替换重复值
replace duplicate values with NA in time series data using dplyr
我的数据似乎与其他类似帖子有点不同。
box_num date x y
1-Q 2018-11-18 20.2 8
1-Q 2018-11-25 21.23 7.2
1-Q 2018-12-2 21.23 23
98-L 2018-11-25 0.134 9.3
98-L 2018-12-2 0.134 4
76-GI 2018-12-2 22.734 4.562
76-GI 2018-12-9 28 4.562
这里我想用 NA 替换 x 和 y 列中的重复值。
我尝试使用 dplyr 的代码:
(1)df <- df %>% group_by(box_num) %>% arrange(box_num,date) %>%
mutate(df$x[duplicated(df$x),] <- NA)
它创建一个包含所有 NA 的新列,而不是仅仅用 NA 替换重复值
(2)df <- df %>% group_by(box_num) %>% arrange(box_num,date) %>%
distinct(x,.keep_all = TRUE)
第二个只给出不重复的行(我们缺少时间序列)
期望的输出:
box_num date x y
1-Q 2018-11-18 20.2 8
1-Q 2018-11-25 21.23 7.2
1-Q 2018-12-2 NA 23
98-L 2018-11-25 0.134 9.3
98-L 2018-12-2 NA 4
76-GI 2018-12-2 22.734 4.562
76-GI 2018-12-9 28 NA
使用 dplyr
我们可以 group_by
box_num
并使用 mutate_at
x
和 y
列并替换 duplicated
价值 NA
.
library(dplyr)
df %>%
group_by(box_num) %>%
mutate_at(vars(x:y), funs(replace(., duplicated(.), NA)))
# box_num date x y
# <fct> <fct> <dbl> <dbl>
#1 1-Q 2018-11-18 20.2 8
#2 1-Q 2018-11-25 21.2 7.2
#3 1-Q 2018-12-2 NA 23
#4 98-L 2018-11-25 0.134 9.3
#5 98-L 2018-12-2 NA 4
#6 76-GI 2018-12-2 22.7 4.56
#7 76-GI 2018-12-9 28 NA
基本的 R 选项(在这种情况下可能不是最好的)是:
cols <- c("x", "y")
df[cols] <- sapply(df[cols], function(x)
ave(x, df$box_num, FUN = function(x) replace(x, duplicated(x), NA)))
这里有一个 data.table
的选项。将'data.frame'转换为'data.table'(setDT(df1)
,在.SDcols
中指定感兴趣的列,replace
列中的重复元素与NA
和通过将 (:=
) 输出分配回列
来更新这些列
library(data.table)
setDT(df1)[, c('x', 'y') := lapply(.SD, function(x)
replace(x, anyDuplicated(x), NA)), box_num, .SDcols= x:y]
df1
# box_num date x y
#1: 1-Q 2018-11-18 20.200 8.000
#2: 1-Q 2018-11-25 21.230 7.200
#3: 1-Q 2018-12-2 NA 23.000
#4: 98-L 2018-11-25 0.134 9.300
#5: 98-L 2018-12-2 NA 4.000
#6: 76-GI 2018-12-2 22.734 4.562
#7: 76-GI 2018-12-9 28.000 NA
数据
df1 <- structure(list(box_num = c("1-Q", "1-Q", "1-Q", "98-L", "98-L",
"76-GI", "76-GI"), date = c("2018-11-18", "2018-11-25", "2018-12-2",
"2018-11-25", "2018-12-2", "2018-12-2", "2018-12-9"), x = c(20.2,
21.23, 20.2, 0.134, 0.134, 22.734, 28), y = c(8, 7.2, 23, 9.3,
4, 4.562, 4.562)), class = "data.frame",
row.names = c(NA, -7L))
我的数据似乎与其他类似帖子有点不同。
box_num date x y
1-Q 2018-11-18 20.2 8
1-Q 2018-11-25 21.23 7.2
1-Q 2018-12-2 21.23 23
98-L 2018-11-25 0.134 9.3
98-L 2018-12-2 0.134 4
76-GI 2018-12-2 22.734 4.562
76-GI 2018-12-9 28 4.562
这里我想用 NA 替换 x 和 y 列中的重复值。 我尝试使用 dplyr 的代码:
(1)df <- df %>% group_by(box_num) %>% arrange(box_num,date) %>%
mutate(df$x[duplicated(df$x),] <- NA)
它创建一个包含所有 NA 的新列,而不是仅仅用 NA 替换重复值
(2)df <- df %>% group_by(box_num) %>% arrange(box_num,date) %>%
distinct(x,.keep_all = TRUE)
第二个只给出不重复的行(我们缺少时间序列) 期望的输出:
box_num date x y
1-Q 2018-11-18 20.2 8
1-Q 2018-11-25 21.23 7.2
1-Q 2018-12-2 NA 23
98-L 2018-11-25 0.134 9.3
98-L 2018-12-2 NA 4
76-GI 2018-12-2 22.734 4.562
76-GI 2018-12-9 28 NA
使用 dplyr
我们可以 group_by
box_num
并使用 mutate_at
x
和 y
列并替换 duplicated
价值 NA
.
library(dplyr)
df %>%
group_by(box_num) %>%
mutate_at(vars(x:y), funs(replace(., duplicated(.), NA)))
# box_num date x y
# <fct> <fct> <dbl> <dbl>
#1 1-Q 2018-11-18 20.2 8
#2 1-Q 2018-11-25 21.2 7.2
#3 1-Q 2018-12-2 NA 23
#4 98-L 2018-11-25 0.134 9.3
#5 98-L 2018-12-2 NA 4
#6 76-GI 2018-12-2 22.7 4.56
#7 76-GI 2018-12-9 28 NA
基本的 R 选项(在这种情况下可能不是最好的)是:
cols <- c("x", "y")
df[cols] <- sapply(df[cols], function(x)
ave(x, df$box_num, FUN = function(x) replace(x, duplicated(x), NA)))
这里有一个 data.table
的选项。将'data.frame'转换为'data.table'(setDT(df1)
,在.SDcols
中指定感兴趣的列,replace
列中的重复元素与NA
和通过将 (:=
) 输出分配回列
library(data.table)
setDT(df1)[, c('x', 'y') := lapply(.SD, function(x)
replace(x, anyDuplicated(x), NA)), box_num, .SDcols= x:y]
df1
# box_num date x y
#1: 1-Q 2018-11-18 20.200 8.000
#2: 1-Q 2018-11-25 21.230 7.200
#3: 1-Q 2018-12-2 NA 23.000
#4: 98-L 2018-11-25 0.134 9.300
#5: 98-L 2018-12-2 NA 4.000
#6: 76-GI 2018-12-2 22.734 4.562
#7: 76-GI 2018-12-9 28.000 NA
数据
df1 <- structure(list(box_num = c("1-Q", "1-Q", "1-Q", "98-L", "98-L",
"76-GI", "76-GI"), date = c("2018-11-18", "2018-11-25", "2018-12-2",
"2018-11-25", "2018-12-2", "2018-12-2", "2018-12-9"), x = c(20.2,
21.23, 20.2, 0.134, 0.134, 22.734, 28), y = c(8, 7.2, 23, 9.3,
4, 4.562, 4.562)), class = "data.frame",
row.names = c(NA, -7L))