Div*_*ivi 2 r dplyr data.table
可重复的数据集:
library(data.table)
library(dplyr)
library(zoo)
df = expand.grid(ID = sample(LETTERS[1:5]),
Date = seq.Date(as.Date("2012-01-01"), as.Date("2012-12-01"), by = "1 month"))
df = df[order(as.character(df$ID)),]
df = data.table(df, V1 = runif(nrow(df),0,1), V2 = runif(nrow(df),0,1), V3 = runif(nrow(df),0,1))
ind = sample(nrow(df), nrow(df)*.5)
na.gen <- function(x, ind){x[ind] <- NA}
df1 <- df %>% slice(., ind) %>% mutate_each(funs(na.gen), starts_with("V"))
df2 = df[!ind]
df <- rbind(df1, df2)
df <- df[order(as.character(df$ID), df$Date),]
df$ID = as.character(df$ID)
Run Code Online (Sandbox Code Playgroud)
在上面的数据集中,我的想法是使用Last Observation Carried Forward方法来估算数据.我原来的问题是一个非常大的数据集,所以我测试dplyr和data.table解决方案.
final_dplyr <- df %>% group_by(ID) %>% mutate_each(funs(na.locf), starts_with("V"))
final_data.table <- df[, na.locf(.SD), by = ID]
Run Code Online (Sandbox Code Playgroud)
data.table然而,给我正确的解决方案,dplyr混淆了从NA开始的子集.我收到以下警告dplyr:
Warning messages:
1: In `[.data.table`(`_dt`, , `:=`(V1, na.locf(V1)), by = `_vars`) :
Supplied 11 items to be assigned to group 1 of size 12 in column 'V1' (recycled leaving remainder of 1 items).
Run Code Online (Sandbox Code Playgroud)
可以帮我理解我做错了dplyr什么?
好的,这里发生了很多事情.首先,正如@Frank所说,这两个命令对不同的对象进行操作.na.locf(.SD)在子集data.table每个ID,其中,作为dplyr的上分别各列每个ID.
要确定问题的位置,我将使用data.table相当于您的dplyr语法.
df[, lapply(.SD, na.locf), by=ID]
# warning
Run Code Online (Sandbox Code Playgroud)
我们收到相同的警告信息.对于1个或多个组,每个列返回的行数似乎不相同.我们来检查一下.
df[, lapply(.SD, function(x) length(na.locf(x))), by=ID]
# ID Date V1 V2 V3
# 1: A 12 12 12 12
# 2: B 12 12 12 12
# 3: C 12 11 11 11 # <~~~ we've a winner!
# 4: D 12 12 12 12
# 5: E 12 12 12 12
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
head(df[ID == "C"])
# ID Date V1 V2 V3
# 1: C 2012-01-01 NA NA NA
# 2: C 2012-02-01 0.7475075 0.8917311 0.7601174
# 3: C 2012-03-01 0.4922747 0.7749479 0.3995417
# 4: C 2012-04-01 0.9013631 0.3388313 0.8873779
# 5: C 2012-05-01 NA NA NA
# 6: C 2012-06-01 NA NA NA
nrow(df[ID == "C", na.locf(.SD), .SDcols= -c("ID")])
# 12 as expected
nrow(df[ID == "C", lapply(.SD, na.locf), .SDcols= -c("ID")])
# 12, but with warnings
Run Code Online (Sandbox Code Playgroud)
na.locf()单独使用on列将返回11V1:V4.为什么?这似乎是因为NA一开始.?na.locf有一个na.rm参数,默认设置为TRUE从一开始删除NAs.所以我们将其设置为false并再试一次
nrow(df[ID == "C", lapply(.SD, na.locf, na.rm=FALSE), .SDcols = -c("ID")])
# 12, no warnings
Run Code Online (Sandbox Code Playgroud)
它工作,na.locf(.SD)因为它也运行na.locf在Date返回12行的列上,我想.
实质上,您需要以某种方式设置,或na.rm=FALSE以dplyr某种方式dplyr开始处理整个对象.我不知道怎么做.
PS:请注意,您可以使用:=,以更新引用的data.table不是与data.table语法返回一个新的对象.