简体   繁体   English

R 中的语法,用于在多行上分解分配的 LHS

[英]Syntax in R for breaking up LHS of assignment over multiple lines

What is the syntax in R to break up the LHS of an assignment over multiple lines? R 中用于将分配的 LHS 拆分为多行的语法是什么? In other programming languages you can do it.在其他编程语言中,您可以做到。

One use case of this (and please don't let this example distract from the general syntactical question), is that because (I believe) R doesn't support loop placeholder variables by reference, so when working with very deep nested data structures (like recursive lists of data frames of lists) in a for loop you can sometimes have a very a long LHS of an assignment, eg这个的一个用例(请不要让这个例子分散一般语法问题的注意力)是因为(我相信)R 不支持通过引用循环占位符变量,所以在使用非常深的嵌套数据结构时(像列表的数据帧的递归列表)在 for 循环中你有时可以有一个非常长的分配的 LHS,例如

results$cases[[i]]$samples[[j]]$portions[[k]]$analytes[[l]]$column <- x

I know, you might say why not use nested lapplys or something, but that's a separate discussion.我知道,您可能会说为什么不使用嵌套 lapplys 或其他东西,但那是一个单独的讨论。

I tried wrapping the LHS in parentheses and you get我尝试将 LHS 括在括号中,你得到

Error: could not find function "(<-"

You can put a line break between any 2 characters that aren't part of a name, and that doesn't leave a syntactically complete expression before the line break (so that the parser knows to look for more).您可以在不属于名称的任何 2 个字符之间放置一个换行符,并且在换行符之前不会留下语法上完整的表达式(以便解析器知道要查找更多)。 None of these look great, but basically after any [[ or $ or before ]] you can put a line break.这些看起来都不是很好,但基本上在任何[[$或之前]]之后你都可以换行。 For example:例如:

results$
  cases[[i]]$
    samples[[j]]$
      portions[[k]]$
        analytes[[l]]$
          column <- x

Or going to the extreme, putting in every syntactically valid line break (without introducing parentheses which would let you do even more):或者走极端,放入每个语法上有效的换行符(不引入括号,这会让你做更多的事情):

results$
  cases[[
    i
  ]]$
    samples[[
      j
    ]]$
      portions[[
        k
      ]]$
        analytes[[
          l
        ]]$
          column <-
            x

With parentheses, we lose the "doesn't leave a syntactically complete expression" rule, because the expression won't be complete until the parenthses close.有了圆括号,我们就失去了“不留下句法完整的表达式”规则,因为表达式在圆括号闭合之前是不完整的。 You can add breaks anywhere except in the middle of a name (object or function name).您可以在名称中间以外的任何位置添加分隔符(对象或 function 名称)。 I won't bother with nested indentation for this example.对于这个例子,我不会为嵌套缩进而烦恼。

(
  results
  $
  cases
  [[
    i
  ]]
  $
  samples
  [[
    j
  ]]
  $
  portions
  [[
    k
  ]]
  $
  analytes
  [[
    l
  ]]
  $
  column
  <-
  x
)

If you want to bring attention to the x being assigned, you could also use right assignment.如果你想引起对分配的x的注意,你也可以使用正确的分配。

x -> results$cases[[i]]$samples[[j]]$
       portions[[k]]$analytes[[l]]$column

Just to mention: the element operator [[ supports recursive indexing of lists, as documented in ?Extract under "Recursive (list-like) objects".只需提及:元素运算符[[支持列表的递归索引,如“递归(类列表)对象”下的?Extract中所述。

One caveat is that you must provide an integer or character index for each level of recursion.一个警告是您必须为每个递归级别提供 integer 或字符索引。 Mixtures aren't supported, so you must index by integer if any sublist does not have a names attribute.不支持混合,因此如果任何子列表没有names属性,则必须按 integer 进行索引。

x <- list(a = list(a1 = 1, a2 = 2), b = list(b1 = 3, b2 = 4))

x[[c(1L, 1L)]]
## [1] 1

x[[c("a", "a2")]]
## [1] 2

x[[c(2L, 1L)]] <- 30
x[[c(2L, 1L)]]
## [1] 30

x[[c("b", "b2")]] <- 40
x[[c("b", "b2")]]
## [1] 40

x[[list(1L, "a1")]]
## Error in x[[list(1L, "a1")]] : invalid subscript type 'list'

You can always implement accessors that do support indices of mixed type:您始终可以实现支持混合类型索引的访问器:

rget <- function(x, i) {
    if (is.list(i)) {
        for (j in i) {
            x <- x[[j]]
        }
        x
    } else {
        x[[i]]
    }
}

`rset<-` <- function(x, i, value) {
    if (is.list(i)) {
        y <- x
        n <- length(i)
        ii <- integer(n)
        for (k in seq_len(n)) {
            j <- i[[k]]
            ii[k] <- if (is.character(j)) match(j, names(y)) else j
            y <- y[[j]]
        }
        x[[ii]] <- value
    } else {
        x[[i]] <- value
    }
    x
}

Then:然后:

rget(x, list(1L, "a1"))
## [1] 1

rset(x, list(1L, "a1")) <- 10
rget(x, list(1L, "a1"))
## [1] 10

You would just have to accept the overhead of the for loops.您只需要接受for循环的开销。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM