【发布时间】:2017-01-19 15:59:34
【问题描述】:
问题
我有一个包含 3 个变量的数据集:一个 ID 变量、一个 TIME 变量和一个数字变量 X,只有当它不为零时才会出现在数据集中,如下表所示。
time ID X
238 2007 A 28
239 2008 A 80
240 2014 A 178
241 2012 B 88
242 2011 C 369
243 2003 D 28
244 2004 D 80
我希望在一个唯一的数据框中,每个 ID 都有一个 lign,并且在 2001 年至 2016 年之间的每一年,必要时 X=0。所以这将是一个如下表:
time ID X
1 2001 A 0
2 2002 A 0
7 2007 A 28
8 2008 A 80
14 2014 A 178
17 2001 B 0
7 2012 B 88
我在 R 文档或此论坛中找不到任何方法
我如何进行
为了解决这个问题,我的想法是分三步进行:
1)我每个身份证号只保留一行,不管是哪一年
data2 = data%>%group_by(ID,X)%>%distinct(.keep_all = T)
这导致下表:
time ID X
238 2007 A 28
241 2012 B 88
242 2011 C 369
243 2003 D 28
2)然后我复制每一行以每年进行观察
timebis = seq(from = 2001, to = 2016, by = 1)
dupl.data2 = data2[rep(1:nrow(data1), each=length(timebis)), ]
dupl.data1$X = 0
我现在每个 ID 有 16 个观察值。
3) 用双 for 循环填充 dupl.data1$X 列
i=1
j=1
for(i in 1:length(dupl.data2$ID)){
for(j in 1:length(data$ID)){
if (dupl.data2$timebis[i]==data$time[j] & dupl.data2$ID[i]==data$ID[j])
{dupl.data2$X[i]=data$X[j]}
j=j+1
}
j=1
i=i+1
}
结论
它在小型子样本上效果很好,但我的原始数据库有大约 300 000 个观察值,而带有零的数据集要大得多。 我需要提高我的代码效率或想法来解决这个问题。
谢谢
【问题讨论】:
-
newDf <- merge(df, expand.grid(id=unique(df$id), year=2001:2014), by=c("id", "year"), all=TRUE); df$X[is.na(df$X)] <- 0这样的东西会起作用。 -
使用data.table,
merge(setDT(data), setnames(data[, seq(2001, 2016), by=data$ID], c("ID", "time")), all=TRUE)。所有需要做的就是替换丢失。
标签: r loops for-loop dataframe duplicates