当使用base的stats:::reshape()
将数据从long格式转换为宽格式时,对于任何指定为时间不变量的变量,reshape
只取第一个观察值,如果变量实际上是变化的方式,输出警告。在我的情况下,我遗漏了我想指定为时间不变的变量的数据,但由于我在其他时间点有这些数据,我希望使用这些时间点的值而不是NA
这是第一次观察到的。
testdata <- data.frame(matrix(c(1,1,2,3,4,3.5,NA,6,4,1,2,1), nrow = 3))
colnames(testdata) <- c("id", "process1", "timeinvariant", "time")
# > testdata
# id process1 timeinvariant time
# 1 1 3.0 NA 1
# 2 1 4.0 6 2
# 3 2 3.5 4 1
# Note here the missing data on the invariant process at time 1
reshaped <- reshape(testdata, v.names="process1", direction = "wide")
# > reshaped
# id timeinvariant process1.1 process1.2
# 1 1 NA 3.0 4
# 3 2 4 3.5 NA
当我宁愿接受在时间2(或任何时候)观察到的值时,NA
被传播到宽格式。
答案 0 :(得分:2)
如果每个timeinvariant
始终至少有一个id
的非缺失值,则timeinvariant
的所有(非缺失)值对于每个id
都相同{1}}(因为它的时间不变),您是否无法创建一个新列,填充NA
中的timeinvariant
值,然后使用该列重新整形?例如:
# Add another row to your data frame so that we'll have 2 NA values to deal with
td <- data.frame(matrix(c(1,1,2,1,3,4,3.5,4.5,NA,6,4,NA,1,2,1,3), nrow = 4))
colnames(td) <- c("id", "process1", "timeinvariant", "time")
# Create new column timeinvariant2, which fills in NAs from timeinvariant,
# then reshape using that column
library(dplyr)
td.wide = td %>%
group_by(id) %>%
mutate(timeinvariant2=max(timeinvariant, na.rm=TRUE)) %>%
dcast(id + timeinvariant2 ~ time, value.var='process1')
# Paste "process1." onto names of all "time" columns
names(td.wide) = gsub("(^[0-9]*$)", "process1\\.\\1", names(td.wide) )
td.wide
id timeinvariant2 process1.1 process1.2 process1.3
1 1 6 3.0 4 4.5
2 2 4 3.5 NA NA
答案 1 :(得分:1)
我不知道如何解决问题,但解决问题的一种方法是按顺序将NA值降低。
testdata <- testdata[order(testdata$timeinvariant),]
testdata
# id process1 timeinvariant time
#3 2 3.5 4 1
#2 1 4.0 6 2
#1 1 3.0 NA 1
reshaped<-reshape(testdata,v.names="process1",direction="wide")
reshaped
# id timeinvariant process1.1 process1.2
#3 2 4 3.5 NA
#2 1 6 3.0 4
更通用的解决方案是确保每个id
的timevariant列中只有一个值testdata$timeinvariant <- apply(testdata,1,function(x) max(testdata[testdata$id == x[1],"timeinvariant"],na.rm=T))
testdata
# id process1 timeinvariant time
#3 2 3.5 4 1
#2 1 4.0 6 2
#1 1 3.0 6 1
在调用reshape函数之前,可以对任意数量的列重复此操作。 希望这有帮助