r语言 - 从长到宽的整形,时间不变变量上缺少一些数据 (NA)

  • 本文关键字:变量 NA 数据 时间 r语言 reshape
  • 更新时间 :
  • 英文 :


当使用stats:::reshape() from base将数据从长格式转换为宽格式时,对于指定为时不变的变量,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

NA被传播到宽格式,当我宁愿采用在时间2(或任何时候)观察到的值时。

如果对于每个id总是至少有一个timeinvariant的非缺失值,并且timeinvariant的所有(非缺失)值对于每个id都是相同的(因为它是时不变的),您不能创建一个新列来填充timeinvariant中的NA值,然后使用该列进行重塑吗?例如:

# 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

我不知道如何解决这个问题,但解决这个问题的一种方法是按顺序将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

在时变列中只有一个值
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

在调用重塑函数之前,可以对任意数量的列重复此操作。希望对大家有所帮助

相关内容

  • 没有找到相关文章

最新更新