【问题标题】:Reshaping from long to wide with some missing data (NA's) on time invariant variables在时间不变变量上使用一些缺失数据 (NA) 从长到宽进行重塑
【发布时间】:2014-06-04 17:02:20
【问题描述】:

当使用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(或任何时候)观察到的值。

【问题讨论】:

    标签: r reshape


    【解决方案1】:

    如果每个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
    

    【讨论】:

    • 什么是“%>%”运算符?它是基础 R 还是 dplyr 包的一部分?
    • 它是dplyr 的一部分。它是一个“链接”运算符,允许您一个接一个地运行函数,而不是嵌套它们。
    • 有关详细信息,请参阅dplyr 小插图的链接部分:cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html
    【解决方案2】:

    我不知道如何解决问题,但解决症状的一种方法是将 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 函数之前,可以对任意数量的列重复此操作。 希望这会有所帮助

    【讨论】:

    • 是的,这将是一个问题。我没有使用 reshape 包,所以不知道所有选项。这个解决方案只是一个 hack。另一种方法是将 timeinvariant 列中的值替换为每个 id 的单个值。例如查找最大值并用最大值替换所有值 testdata$test
    猜你喜欢
    • 2021-10-23
    • 2011-07-14
    • 1970-01-01
    • 2018-05-05
    • 2011-03-20
    • 2018-02-17
    • 1970-01-01
    • 2020-07-12
    • 2014-05-12
    相关资源
    最近更新 更多