将 NULL 分配给 R 中的列表元素?

发布于 2024-12-12 20:23:14 字数 640 浏览 0 评论 0原文

我发现这种行为很奇怪,希望更多有经验的用户分享他们的想法和解决方法。 在 R 中运行下面的代码示例时:

sampleList <- list()
d<- data.frame(x1 = letters[1:10], x2 = 1:10, stringsAsFactors = FALSE)
for(i in 1:nrow(d)) {
        sampleList[[i]] <- d$x1[i]
}

print(sampleList[[1]])
#[1] "a"
print(sampleList[[2]])
#[1] "b"
print(sampleList[[3]])
#[1] "c"
print(length(sampleList))
#[1] 10

sampleList[[2]] <- NULL
print(length(sampleList))
#[1] 9
print(sampleList[[2]])
#[1] "c"
print(sampleList[[3]])
#[1] "d"

列表元素向上移动。 也许这正如预期的那样,但我正在尝试实现一个函数,其中合并列表的两个元素并删除一个。我基本上想丢失该列表索引或将其设置为 NULL。

有什么方法可以将 NULL 分配给它并且看不到上述行为吗?

感谢您的建议。

I found this behaviour odd and wanted more experienced users to share their thoughts and workarounds.
On running the code sample below in R:

sampleList <- list()
d<- data.frame(x1 = letters[1:10], x2 = 1:10, stringsAsFactors = FALSE)
for(i in 1:nrow(d)) {
        sampleList[[i]] <- d$x1[i]
}

print(sampleList[[1]])
#[1] "a"
print(sampleList[[2]])
#[1] "b"
print(sampleList[[3]])
#[1] "c"
print(length(sampleList))
#[1] 10

sampleList[[2]] <- NULL
print(length(sampleList))
#[1] 9
print(sampleList[[2]])
#[1] "c"
print(sampleList[[3]])
#[1] "d"

The list elements get shifted up.
Maybe this is as expected, but I am trying to implement a function where I merge two elements of a list and drop one. I basically want to lose that list index or have it as NULL.

Is there any way I can assign NULL to it and not see the above behaviour?

Thank you for your suggestions.

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

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

发布评论

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

评论(5

话少情深 2024-12-19 20:23:15

我花了一段时间才弄清楚这个列表的列表。我的解决方案是:

mylist[[i]][j] <- list(double())

Took me a while to figure this one out for a list of lists. My solution was:

mylist[[i]][j] <- list(double())
内心激荡 2024-12-19 20:23:14

好问题。

查看R-FAQ

在 R 中,如果 x 是一个列表,则 x[i] <- NULL 和 x[[i]] <- NULL 从 x 中删除指定元素。其中第一个与 S 不兼容,它是无操作的。 (请注意,您可以使用 x[i] <- list(NULL) 将元素设置为 NULL。)

请考虑以下示例:

> t <- list(1,2,3,4)
> t[[3]] <- NULL          # removing 3'd element (with following shifting)
> t[2] <- list(NULL)      # setting 2'd element to NULL.
> t
[[1]]
[2] 1

[[2]]
NULL

[[3]]
[3] 4

更新:

作为 R Inferno评论道,处理NULL时可能会出现更微妙的情况。考虑相当一般的代码结构:

# x is some list(), now we want to process it.
> for (i in 1:n) x[[i]] <- some_function(...)

现在请注意,如果 some_function() 返回 NULL,您可能不会得到您想要的:某些元素将消失 。你应该使用lapply函数。
看看这个玩具示例:

> initial <- list(1,2,3,4)
> processed_by_for <- list(0,0,0,0)
> processed_by_lapply <- list(0,0,0,0)
> toy_function <- function(x) {if (x%%2==0) return(x) else return(NULL)}
> for (i in 1:4) processed_by_for[[i]] <- toy_function(initial[[i]])
> processed_by_lapply <- lapply(initial, toy_function)
> processed_by_for
  [[1]]
  [1] 0

  [[2]]
  [1] 2

  [[3]]
  NULL

  [[4]]
  [1] 4

> processed_by_lapply
  [[1]]
  NULL

  [[2]]
  [1] 2

  [[3]]
  NULL

  [[4]]
  [1] 4

Good question.

Check out the R-FAQ:

In R, if x is a list, then x[i] <- NULL and x[[i]] <- NULL remove the specified elements from x. The first of these is incompatible with S, where it is a no-op. (Note that you can set elements to NULL using x[i] <- list(NULL).)

consider the following example:

> t <- list(1,2,3,4)
> t[[3]] <- NULL          # removing 3'd element (with following shifting)
> t[2] <- list(NULL)      # setting 2'd element to NULL.
> t
[[1]]
[2] 1

[[2]]
NULL

[[3]]
[3] 4

UPDATE:

As the author of the R Inferno commented, there can be more subtle situations when dealing with NULL. Consider pretty general structure of code:

# x is some list(), now we want to process it.
> for (i in 1:n) x[[i]] <- some_function(...)

Now be aware, that if some_function() returns NULL, you maybe will not get what you want: some elements will just disappear. you should rather use lapply function.
Take a look at this toy example:

> initial <- list(1,2,3,4)
> processed_by_for <- list(0,0,0,0)
> processed_by_lapply <- list(0,0,0,0)
> toy_function <- function(x) {if (x%%2==0) return(x) else return(NULL)}
> for (i in 1:4) processed_by_for[[i]] <- toy_function(initial[[i]])
> processed_by_lapply <- lapply(initial, toy_function)
> processed_by_for
  [[1]]
  [1] 0

  [[2]]
  [1] 2

  [[3]]
  NULL

  [[4]]
  [1] 4

> processed_by_lapply
  [[1]]
  NULL

  [[2]]
  [1] 2

  [[3]]
  NULL

  [[4]]
  [1] 4
三生路 2024-12-19 20:23:14

你的问题让我有点困惑。

将 null 分配给现有对象本质上会删除该对象(例如,如果您有一个数据框并希望删除特定列,这会非常方便)。这就是你所做的。我无法确定你想要什么。您可以尝试

sampleList[[2]] <- NA

代替 NULL,但如果“我想失去”您的意思是删除它,那么您已经成功了。这就是为什么“列表元素向上移动”。

Your question is a bit confusing to me.

Assigning null to an existing object esentially deletes that object (this can be very handy for instance if you have a data frame and wish to delete specific columns). That's what you've done. I am unable to determine what it is that you want though. You could try

sampleList[[2]] <- NA

instead of NULL, but if by "I want to lose" you mean delete it, then you've already succeeded. That's why, "The list elements get shifted up."

秉烛思 2024-12-19 20:23:14
obj = list(x = "Some Value")
obj = c(obj,list(y=NULL)) #ADDING NEW VALUE
obj['x'] = list(NULL) #SETTING EXISTING VALUE
obj
obj = list(x = "Some Value")
obj = c(obj,list(y=NULL)) #ADDING NEW VALUE
obj['x'] = list(NULL) #SETTING EXISTING VALUE
obj
泪之魂 2024-12-19 20:23:14

如果您需要创建 NULL 值列表,稍后您可以使用值(例如数据帧)填充这里没有抱怨

B <-vector("list", 2) 

a <- iris[sample(nrow(iris), 10), ]
b <- iris[sample(nrow(iris), 10), ]
B[[1]]<-a 
B[[2]]<-b 

上面的答案是相似的,但我认为这是值得发布的。

If you need to create a list of NULL values which later you can populate with values (dataframes, for example) here is no complain:

B <-vector("list", 2) 

a <- iris[sample(nrow(iris), 10), ]
b <- iris[sample(nrow(iris), 10), ]
B[[1]]<-a 
B[[2]]<-b 

The above answers are similar, but I thought this was worth posting.

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