[英]How to use the tidyr complete and fill functions to extend a column of NA's in R dataframe?
[英]R - how to fill NA's between two corresponding ID's in a dataframe
我試圖采取以下數據集並將其轉換為第二個。 基本上,我正在嘗試使用該ID填寫每個ID之間的NA。
每個ID對應兩個時間戳,我加入了一個更大的date_time列。 出於再現能力的目的,在連接之間執行sql(date_time列非常大)或甚至采用原始數據集並在每個id之間創建時間戳然后將其加入(我有太多ID是這樣做的)。 我已經成功完成了這兩種方法,只需花費太多時間來處理我的數據量。 我希望用這個數據集操縱數據。 這看起來很簡單,但真的讓我難過。 任何幫助,將不勝感激。
當前數據集:
date_time id
<dttm> <dbl>
1 2017-01-30 08:00:00 NA
2 2017-01-30 08:00:01 NA
3 2017-01-30 08:00:02 1
4 2017-01-30 08:00:03 NA
5 2017-01-30 08:00:04 NA
6 2017-01-30 08:00:05 NA
7 2017-01-30 08:00:06 NA
8 2017-01-30 08:00:07 1
9 2017-01-30 08:00:08 NA
10 2017-01-30 08:00:09 NA
11 2017-01-30 08:00:10 2
12 2017-01-30 08:00:11 NA
13 2017-01-30 08:00:12 NA
14 2017-01-30 08:00:13 NA
15 2017-01-30 08:00:14 2
16 2017-01-30 08:00:15 NA
17 2017-01-30 08:00:16 3
18 2017-01-30 08:00:17 NA
19 2017-01-30 08:00:18 3
20 2017-01-30 08:00:19 NA
期望的數據集:
date_time id
<dttm> <dbl>
1 2017-01-30 08:00:00 NA
2 2017-01-30 08:00:01 NA
3 2017-01-30 08:00:02 1
4 2017-01-30 08:00:03 1
5 2017-01-30 08:00:04 1
6 2017-01-30 08:00:05 1
7 2017-01-30 08:00:06 1
8 2017-01-30 08:00:07 1
9 2017-01-30 08:00:08 NA
10 2017-01-30 08:00:09 NA
11 2017-01-30 08:00:10 2
12 2017-01-30 08:00:11 2
13 2017-01-30 08:00:12 2
14 2017-01-30 08:00:13 2
15 2017-01-30 08:00:14 2
16 2017-01-30 08:00:15 NA
17 2017-01-30 08:00:16 3
18 2017-01-30 08:00:17 3
19 2017-01-30 08:00:18 3
20 2017-01-30 08:00:19 NA
dput()日期:
structure(list(date_time = structure(c(1485781200, 1485781201,
1485781202, 1485781203, 1485781204, 1485781205, 1485781206, 1485781207,
1485781208, 1485781209, 1485781210, 1485781211, 1485781212, 1485781213,
1485781214, 1485781215, 1485781216, 1485781217, 1485781218, 1485781219
), class = c("POSIXct", "POSIXt"), tzone = ""), trx_id = c(NA_real_,
NA_real_, 1, NA_real_, NA_real_, NA_real_, NA_real_, 1,
NA_real_, NA_real_, 2, NA_real_, NA_real_, NA_real_, 2,
NA_real_, 3, NA_real_, 3, NA_real_)), .Names = c("date_time",
"trx_id"), row.names = c(NA, -20L), class = c("tbl_df", "tbl",
"data.frame"))
一種解決方案可以是使用來自tidyr
fill
功能。 方法很簡單。 首先為prev
和next
值創建一列各一列。 使用fill
填充兩列中的缺失值。
現在,對於在prev_val
和next_val
具有相同值的行,應該使用prev_val
更新該值(這意味着那些缺失值在相同的數字之間)
df <- read.table(text = "sl date_time, value
1 '2017-01-30 08:00:00' NA
2 '2017-01-30 08:00:01' NA
3 '2017-01-30 08:00:02' 1
4 '2017-01-30 08:00:03' NA
5 '2017-01-30 08:00:04' NA
6 '2017-01-30 08:00:05' NA
7 '2017-01-30 08:00:06' NA
8 '2017-01-30 08:00:07' 1
9 '2017-01-30 08:00:08' NA
10 '2017-01-30 08:00:09' NA
11 '2017-01-30 08:00:10' 2
12 '2017-01-30 08:00:11' NA
13 '2017-01-30 08:00:12' NA
14 '2017-01-30 08:00:13' NA
15 '2017-01-30 08:00:14' 2
16 '2017-01-30 08:00:15' NA
17 '2017-01-30 08:00:16' 3
18 '2017-01-30 08:00:17' NA
19 '2017-01-30 08:00:18' 3
20 '2017-01-30 08:00:19' NA", header = T, stringsAsFactor = F)
#use fill to find missing values
df %>%
mutate(prev_val = (value), next_val = (value)) %>%
fill(prev_val, .direction = "down") %>%
fill(next_val, .direction = "up") %>%
mutate(value = ifelse(prev_val == next_val, prev_val, value )) %>%
select(-prev_val, -next_val)
Result:
sl date_time. value
1 1 2017-01-30 08:00:00 NA
2 2 2017-01-30 08:00:01 NA
3 3 2017-01-30 08:00:02 1
4 4 2017-01-30 08:00:03 1
5 5 2017-01-30 08:00:04 1
6 6 2017-01-30 08:00:05 1
7 7 2017-01-30 08:00:06 1
8 8 2017-01-30 08:00:07 1
9 9 2017-01-30 08:00:08 NA
10 10 2017-01-30 08:00:09 NA
11 11 2017-01-30 08:00:10 2
12 12 2017-01-30 08:00:11 2
13 13 2017-01-30 08:00:12 2
14 14 2017-01-30 08:00:13 2
15 15 2017-01-30 08:00:14 2
16 16 2017-01-30 08:00:15 NA
17 17 2017-01-30 08:00:16 3
18 18 2017-01-30 08:00:17 3
19 19 2017-01-30 08:00:18 3
20 20 2017-01-30 08:00:19 NA
這是一個base R
選項。 我們使用'trx_id'(一個OP顯示為輸入數據) split
數據集的行序列,獲取序列( seq
),將其stack
到兩個列數據集並將'trx_id'分配給'd1'的'ind'列'基於'值'作為'd1'的索引
d1 <- stack(lapply(split(seq_len(nrow(df1)), df1$trx_id), function(x) seq(x[1], x[2])))
df1$trx_id[d1$values] <- d1$ind
df1$trx_id
#[1] NA NA 1 1 1 1 1 1 NA NA 2 2 2 2 2 NA 3 3 3 NA
非tidyr方法,其中x是您的id列:
x <- c(NA,NA, 1,NA,NA,1, NA, NA, 2, NA, NA,2, NA, 3,NA, NA,3,NA)
timestamps <- paste(unique(x)[!is.na(unique(x))], collapse = "|")
timestamps <- grep(timestamps, x)
timestamps <- matrix(timestamps, ncol = 2, byrow=TRUE)
xmatrix <- apply(timestamps, MARGIN = 1, FUN = function(i) {
y <- x[i[1]:i[2]]
y[is.na(y)] <- x[i][1]
x[i[1]:i[2]] <- y
return(x)
})
(x <- apply(xmatrix, 1,FUN = function(z) {
ifelse(all(is.na(z)), NA, max(z, na.rm=TRUE))
}))
## [1] NA NA 1 1 1 1 NA NA 2 2 2 2 NA 3 3 3 3 NA
HTH
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.