在一行中为 LHS 分配多个新变量
我想在 R 中的一行中分配多个变量。是否可以执行这样的操作?
values # initialize some vector of values
(a, b) = values[c(2,4)] # assign a and b to values at 2 and 4 indices of 'values'
通常我想在一行中分配大约 5-6 个变量,而不是多行。还有其他选择吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
我整理了一个 R 包 zeallot 来解决这个问题。 zeallot 包含一个用于解包、多重和解构赋值的运算符 (
%<-%
)。赋值表达式的 LHS 是通过调用c()
构建的。分配表达式的RHS可以是任何返回或返回或为向量,列表,嵌套列表,数据框架,字符串,日期对象或自定义对象的表达式(假设有destruct
实现)。这是使用 zeallot(最新版本,0.0.5)重新设计的初始问题。
有关更多示例和信息,可以查看包 vignette。
I put together an R package zeallot to tackle this very problem. zeallot includes an operator (
%<-%
) for unpacking, multiple, and destructuring assignment. The LHS of the assignment expression is built using calls toc()
. The RHS of the assignment expression may be any expression which returns or is a vector, list, nested list, data frame, character string, date object, or custom objects (assuming there is adestructure
implementation).Here is the initial question reworked using zeallot (latest version, 0.0.5).
For more examples and information one can check out the package vignette.
关于挣扎有一个很好的答案通过问题博客
这是从那里获取的,做了很小的修改。
使用以下三个功能
(加一以允许不同大小的列表)
然后执行:
使用新函数
g()
对左侧进行分组右侧应该是向量或列表
使用新创建的二元运算符
%=%
使用不同大小的列表的示例:
较长的左侧
较长的右侧
There is a great answer on the Struggling Through Problems Blog
This is taken from there, with very minor modifications.
USING THE FOLLOWING THREE FUNCTIONS
(Plus one for allowing for lists of different sizes)
Then to execute:
Group the left hand side using the new function
g()
The right hand side should be a vector or a list
Use the newly-created binary operator
%=%
Example using lists of different sizes:
Longer Left Hand Side
Longer Right Hand Side
考虑使用基础 R 中包含的功能。
例如,创建一个 1 行数据框(例如
V
)并初始化其中的变量。现在您可以一次分配给多个变量V[,c("a", "b")] <-values[c(2, 4)]
,按名称调用每个变量 (< code>V$a),或同时使用其中多个 (values[c(5, 6)] <- V[,c("a", "b")] )。
如果你很懒并且不想从数据帧中调用变量,你可以
attach(V)
(尽管我个人从来不这样做)。Consider using functionality included in base R.
For instance, create a 1 row dataframe (say
V
) and initialize your variables in it. Now you can assign to multiple variables at onceV[,c("a", "b")] <- values[c(2, 4)]
, call each one by name (V$a
), or use many of them at the same time (values[c(5, 6)] <- V[,c("a", "b")]
).If you get lazy and don't want to go around calling variables from the dataframe, you could
attach(V)
(though I personally don't ever do it).这是我的想法。语法可能非常简单:
如下所示:
但这还没有经过充分测试。
here is my idea. Probably the syntax is quite simple:
gives like this:
this is not well tested though.
一个潜在的危险(与使用
分配一样有风险)选项是<代码>矢量化<代码>分配:
或者我想你可以自己手动对其进行矢量化使用您自己的函数使用
maply
,它可能为envir
参数使用合理的默认值。例如,Vectorize
将返回一个与assign
具有相同环境属性的函数,在本例中为namespace:base
,或者您可以只设置envir =parent.env(environment(assignVec))
。A potentially dangerous (in as much as using
assign
is risky) option would be toVectorize
assign
:Or I suppose you could vectorize it yourself manually with your own function using
mapply
that maybe uses a sensible default for theenvir
argument. For instance,Vectorize
will return a function with the same environment properties ofassign
, which in this case isnamespace:base
, or you could just setenvir = parent.env(environment(assignVec))
.达到了我的目的,即将五个 2 分配给前五个字母。
Served my purpose, i.e., assigning five 2s into first five letters.
正如其他人所解释的,似乎没有任何内置内容。...但是您可以设计一个
vassign
函数,如下所示:需要考虑的一件事是如何处理您指定的情况3 个变量和 5 个值,反之亦然。在这里,我只是重复(或截断)这些值,使其与变量的长度相同。也许警告是谨慎的做法。但它允许以下操作:
As others explained, there doesn't seem to be anything built in. ...but you could design a
vassign
function as follows:One thing to consider though is how to handle the cases where you e.g. specify 3 variables and 5 values or the other way around. Here I simply repeat (or truncate) the values to be of the same length as the variables. Maybe a warning would be prudent. But it allows the following:
最近遇到了类似的问题,这是我使用
purrr::walk2
的尝试Had a similar problem recently and here was my try using
purrr::walk2
https://stat.ethz.ch/R -manual/R-devel/library/base/html/list2env.html:
https://stat.ethz.ch/R-manual/R-devel/library/base/html/list2env.html:
如果您唯一的要求是一行代码,那么:
If your only requirement is to have a single line of code, then how about:
对于命名列表,使用
For example:
会将 foo = 1, bar = 2 添加到当前环境,并覆盖具有这些名称的任何对象。这相当于
This 也适用于函数:
但是,最好对要包含在当前环境中的元素进行命名,以免覆盖另一个对象...所以最好这样写
最后,如果您想要不同的名称对于新导入的对象,写:
相当于
For a named list, use
For instance:
will add foo = 1, bar = 2 to the current environement, and override any object with those names. This is equivalent to
This works in a function, too:
However, it is good practice to name the elements you want to include in the current environment, lest you override another object... and so write preferrably
Finally, if you want different names for the new imported objects, write:
which is equivalent to
不幸的是,恐怕您正在寻找的优雅解决方案(例如
c(a, b) = c(2, 4)
)并不存在。 但不要放弃,我不确定!我能想到的最接近的解决方案是这个:或者如果您对警告感到烦恼,请将其关闭:
但我想您不是对这个解决方案感到满意,我也不会......
I'm afraid that elegent solution you are looking for (like
c(a, b) = c(2, 4)
) unfortunatelly does not exist. But don't give up, I'm not sure! The nearest solution I can think of is this one:or if you are bothered with warnings, switch them off:
But I suppose you're not satisfied with this solution, I wouldn't be either...
结合这里给出的一些答案+一点点盐,这个解决方案怎么样:
我用它在这里添加 R 部分: http://rosettacode.org/wiki/Sort_third_variables#R
警告:它仅适用于分配全局变量(例如<代码><<-)。如果有更好、更通用的解决方案,请。在评论中告诉我。
Combining some of the answers given here + a little bit of salt, how about this solution:
I used this to add the R section here: http://rosettacode.org/wiki/Sort_three_variables#R
Caveat: It only works for assigning global variables (like
<<-
). If there is a better, more general solution, pls. tell me in the comments.另一个带有递归的版本:
示例:
我的版本:
示例:
Another version with recursion:
example:
My version:
example: