R:交换两个变量而不使用第三个

q9yhzks0  于 2023-04-18  发布在  其他
关注(0)|答案(8)|浏览(95)

我有两个变量(即):

a <- 1
   b <- 2

我想交换它们的值。是否有任何内置的R函数,能够执行该操作?或者有其他优雅的方法,而不使用第三个(临时)变量?

**注意:**如果可能,适用于字符串或其他数据类型。

7lrncoxx

7lrncoxx1#

有一个通用的解决方案或“技巧”:

a <- 1
b <- 2

a <- a + b
b <- a - b
a <- a - b

这里有一个有用的链接,解释了很多:xor-trick

svdrlsy4

svdrlsy42#

对于整数,可以使用

a = a + b
b = a - b
a = a - b

对于弦来说这是可行的

a <- "one"
b <- "two"
a <- paste(a,b, sep = "")
b <- substr(a,0,nchar(a) - nchar(b))
a <- substr(a,nchar(b) + 1, nchar(a))

> a
# two
> b 
# one
bvjxkvbb

bvjxkvbb3#

在基本包中有太多函数的好处是:总有办法去做一些事,即使是个坏主意。

list2env(list(a = b, b = a), envir = .GlobalEnv)

不管ab的类是什么,这都是有效的。这是个坏主意

gajydyqb

gajydyqb4#

开始

A = 9
B = 5
A = A + B

然后

A is 14
B is 5
B = A - B

然后

A is 14
B is 9
A = A - B

结果:
A(5)现在是B
B(9)现在是A
不是真的简单,然后只是使用第三个变量,但我的作品!

axr492tv

axr492tv5#

虽然前面的答案都很好很漂亮,但它们都占用了太多我喜欢的空间!
所以我在C中提出了一个更整洁的解决方案:

a = (b - a) + (b = a);

它不能处理字符串,但整数和浮点数都可以。
它是这样工作的:

int a = 5, b = 7;
a = (b - a) + (b = a);
/* turns into */
a = (7 - 5) + (b = 5);
/* b is now 5 */
a = 2 + 5;
/* a is now 7 */

这里的关键是解析表达式的顺序(从左到右)。因此,表达式中第一次出现的 b 被替换为 b 的原始值,只有在此之后,b 才被分配给 a
我知道这是一个古老的问题,而且已经有了答案,但也许这对外面的人会有用

gstyhher

gstyhher6#

根据Nathan的帖子,为了在运行环境中保持变量交换:

x <- 10
y <- 20
list2env(list(x=y, y=x), envir=as.environment(environment()))
print(x)
print(y)
fxnxkyjh

fxnxkyjh7#

据我所知,没有内置函数可以做到这一点,也没有通用的方法可以在没有第三个变量的情况下交换两个变量。
但是,如果您正在寻找一个至少可以减少代码重复的函数,则以下内容可能会有所帮助:

swap <- function(x,y) {
  eval( parse( text = paste(
    "swap_unique_var_a<-", substitute(x), ";",
    substitute(x), "<-", substitute(y), ";",
    substitute(y), "<-swap_unique_var_a") ), env=parent.frame() )
}

然后,您可以按如下方式使用它:

a<-1; b<-2;
swap(a,b)
print(a); print(b)

函数swap()的两个参数引用本地帧中的两个变量,然后交换它们,从而创建一个临时变量。
swap()功能的当前限制/问题:

  • 临时文件是在parent.frame()中创建的,这是您调用swap()的地方。
  • 假设参数xyparent.frame()环境中,因此全局环境中的变量在parent.frame()环境中重新创建。

也许可以使函数更健壮,但我有点担心对性能的影响,特别是在解释性语言中,如R,没有等效的内联。
如果有兴趣/时间,我将测试性能,看看是否有可能有一个更健壮的版本。

xxslljrj

xxslljrj8#

你可以在list中临时存储值,也可以在其中进行赋值。但是我不推荐这种方式,只是为了展示另一种可能性。

a <- 1
b <- 2

b <- list(a, a <- b)[[1]]

a
#[1] 2
b
#[1] 1

使用临时变量可能更容易阅读,并且可能更高效。

a <- 1
b <- 2

. <- a
a <- b
b <- .
rm(.)

a
#[1] 2
b
#[1] 1

相关问题