防止 unlist 删除 NULL 值

发布于 2024-09-05 04:23:12 字数 384 浏览 5 评论 0原文

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

我怎样才能防止这种情况发生?

这是一个简单(非)工作示例,展示了 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 

I have a vector of lists and I use unlist on them. Some of the elements in the vectors are NULL and unlist seems to be dropping them.

How can I prevent this?

Here's a simple (non) working example showing this unwanted feature of 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 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

瑾兮 2024-09-12 04:23:12

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

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

In this case (one level depth list) this should works too:

a[sapply(a, is.null)] <- NA
unlist(a)
# p1 p2 p1 p2 p1 p2 p1 p2 
#  2  5  3  4 NA NA  4  5
白况 2024-09-12 04:23:12

这里的问题是向量中间不能有 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 `

The issue here is that you can't have NULL in the middle of a vector. For example:

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

You can have NA in the middle though. You could could convert it to character and then back to numeric, which automatically converts the NULL values to NA (with a warning):

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

then put the names back in, because they've been dropped by the previous operation:

> names(b) <- names(a)
> b
p1 p2 p1 p2 p1 p2 p1 p2 
2  5  3  4 NA NA  4  5 `
无法回应 2024-09-12 04:23:12

如果您正在处理具有多个级别的长而复杂的 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]]

If you are dealing with a long complex JSON with several levels you should give this a try:

I extracted game log data from nba.com/stats web site. The problem is, some players have a NULL value for 3 point free throws (mostly centers) and jsonlite::fromJSON seems to handle NULL values very well:

#### 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]]
倥絔 2024-09-12 04:23:12

使用 purrrtidyverse 解决方案

a <- map(a, ~ifelse(is.null(.x), NA, .x))
a %>% unlist()

或者如果您想一次完成所有操作:

map_vec(a, ~ifelse(is.null(.x), NA, .x))

A tidyverse solution using purrr

a <- map(a, ~ifelse(is.null(.x), NA, .x))
a %>% unlist()

Or if you want to do everything at once:

map_vec(a, ~ifelse(is.null(.x), NA, .x))
眼眸 2024-09-12 04:23:12

指示缺失值的正确方法是 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 

The correct way to indicate a missing value is NA (not NULL). Here is another version that is working:

   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 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文