【问题标题】:Prevent unlist to drop NULL values防止 unlist 删除 NULL 值
【发布时间】:2011-02-28 19:25:29
【问题描述】:

我有一个列表向量,我在它们上使用unlist。向量中的一些元素是 NULLunlist 似乎正在删除它们。

如何防止这种情况发生?

这是一个简单(非)工作示例,显示了unlist 的这个不需要的功能

a = c(list("p1"=2, "p2"=5), 
      list("p1"=3, "p2"=4), 
      list("p1"=NULL, "p2"=NULL), 
      list("p1"=4, "p2"=5))
unlist(a)
 p1 p2 p1 p2 p1 p2 
 2  5  3  4  4  5 

【问题讨论】:

    标签: list r null


    【解决方案1】:

    在这种情况下(一级深度列表),这也应该有效:

    a[sapply(a, is.null)] <- NA
    unlist(a)
    # p1 p2 p1 p2 p1 p2 p1 p2 
    #  2  5  3  4 NA NA  4  5
    

    【讨论】:

    • a[sapply(a, function(x) length(x)==0L)]
    • 感谢@Ferraoo,这对我有用,但 is.null 没有。
    【解决方案2】:

    这里的问题是你不能在向量中间有NULL。例如:

    > c(1,NULL,3)
    [1] 1 3
    

    不过,您可以在中间使用 NA。您可以将其转换为字符,然后再转换回数字,这会自动将 NULL 值转换为 NA(带有警告):

    > b <- as.numeric(as.character(a))
    Warning message:
    NAs introduced by coercion 
    

    然后将名称放回原处,因为它们已被先前的操作删除:

    > names(b) <- names(a)
    > b
    p1 p2 p1 p2 p1 p2 p1 p2 
    2  5  3  4 NA NA  4  5 `
    

    【讨论】:

    • 在 3.2.2 上,看起来 as.numeric(as.character(NULL)) 返回 numeric(0)。一种新方法可能是使用 lapply(b, function(x) ifelse(is.null(x), NA, x))
    • 对于@cylondude 建议的方法,将 sapply 替换为 lapply (或使用 lapply 并简化 = TRUE)以获得向量而不是列表。
    【解决方案3】:

    如果您正在处理具有多个级别的长而复杂的 JSON,您应该尝试一下:

    我从 nba.com/stats 网站提取了比赛日志数据。问题是,一些球员的 3 分罚球(主要是中锋)的值为 NULL,而 jsonlite::fromJSON 似乎很好地处理了 NULL 值:

    #### Player game logs URL: one record per player per game played ####
    gameLogsURL <- paste("http://stats.nba.com/stats/leaguegamelog?Counter=1000&Direction=DESC&LeagueID=00&PlayerOrTeam=P&Season=2016-17&SeasonType=Regular+Season&Sorter=PTS")
    
    #### Import game logs data from JSON ####
    # use jsonlite::fromJSON to handle NULL values
    gameLogsData <- jsonlite::fromJSON(gameLogsURL, simplifyDataFrame = TRUE)
    # Save into a data frame and add column names
    gameLogs <- data.frame(gameLogsData$resultSets$rowSet)
    colnames(gameLogs) <- gameLogsData$resultSets$headers[[1]]
    

    【讨论】:

      【解决方案4】:

      表示缺失值的正确方法是 NA(非 NULL)。这是另一个正在运行的版本:

         a = c(list("p1"=2, "p2"=5),
            list("p1"=3, "p2"=4),
            list("p1"=NA, "p2"=NA),
            list("p1"=4, "p2"=5))
        unlist(a)
      
      p1 p2 p1 p2 p1 p2 p1 p2 
       2  5  3  4 NA NA  4  5 
      

      【讨论】:

      • 感谢您的回答。显然我没有手动定义列表,它是由函数返回的。无论如何,在unlist 之前将 NULL 更改为 NA 似乎可以解决问题。
      • @nico 如果这是你的函数,那么你可以考虑重写它以返回 NA 而不是 NULL。查看NANULL 的帮助页面,了解这两个对象之间的差异。
      • @Marek:不,它实际上是通过在nls 返回的对象列表上应用coef 返回的列表。其中一些对象为 NULL,coef(NULL) 返回NULL...
      猜你喜欢
      • 2021-08-17
      • 1970-01-01
      • 2017-05-29
      • 1970-01-01
      • 2012-08-13
      • 2013-06-05
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多