【问题标题】:Vectorized alternative for swapping用于交换的矢量化替代方案
【发布时间】:2013-10-09 14:23:56
【问题描述】:

我正在尝试使用此代码的矢量化替代方案:

x=read.table("1.txt")
for(i in 1:nrowx)
{
  if(x[i,1]>x[i,2])             
  {
    temp=x[i,1]
    x[i,1]=x[i,2]
    x[i,2]=temp
    x[i,3]=(x[i,3]*(-1))
  }
}   

我尝试使用变换功能:

x <- transform(x, 
               x[[1]] <- ifelse(x[[1]]>x[[2]], x[[2]], x[[1]]), 
               x[[2]] <- ifelse(x[[1]]>x[[2]], x[[1]], x[[2]]),
               x[[3]] <- ifelse(x[[1]]>x[[2]], -x[[3]], x[[3]]))

但是没有成功。返回原始文件,不执行任何操作。

在 x 中读取文件的几行:

"X1" "X2" "X3"
"1" 10 4 1440
"2" 10 4 3765
"3" 10 22 523
"4" 10 295 730
"5" 10 295 1599
"6" 10 584 1872
"7" 10 403 1872
"8" 10 403 1872
"9" 10 281 554
"10" 10 123 554

请帮忙。谢谢!

【问题讨论】:

  • transform 的语法错误。该函数像任何其他函数一样接受参数,因此第一个参数之后的元素应该采用foo = bar 的形式,其中bar 是将包含在返回对象中的对象/结果,foo 是其名称它在返回的对象中分配。也许你在想within()?该函数的语法与您显示的相似。此外,如果您没有引用 x *by name. Each of the three statements you include could all be done outside of transform()` 中的任何对象,则不需要 transform

标签: r loops transform vectorization


【解决方案1】:

我会使用[ 对相关行进行子集化,并使用rev 交换列(现在cbind 包括您想要乘以-1 的列)...当然这个现在变得比我想要的更复杂和不可读的操作,因为您没有在 OP 中完全说明您的要求。请下次再做。

x[ x[,1] > x[,2] , 1:3 ] <- cbind( rev( x[ x[,1] > x[,2] , 1:2 ] ) , 
                                        x[ x[,1] > x[,2] , 3 ] * -1 )
#   X1  X2    X3
#1   4  10 -1440
#2   4  10 -3765
#3  10  22   523
#4  10 295   730
#5  10 295  1599
#6  10 584  1872
#7  10 403  1872
#8  10 403  1872
#9  10 281   554
#10 10 123   554

@BenBolker 建议从子集的行创建一个对象,以使代码更具可读性和效率...

swaprows <- x[,1] > x[,2]
x[swaprows,] <- cbind(rev(x[swaprows,1:2]),-x[swaprows,3])

好多了。

【讨论】:

  • 除了交换之外,我还需要执行另一个操作。每当交换完成时,第 3 列的内容需要乘以 -1。我已在原始问题中进行了必要的编辑。很抱歉之前没有提到它。
  • 您能否也给出包含此内容的答案。谢谢!
  • @phoenix jeez,您仅在 2 分钟前发表了评论。抓住你的马!
  • 为了可读性,可能先设置swaprows &lt;- x[,1] &gt; x[,2],然后设置x[swaprows,] &lt;- cbind(rev(x[swaprows,1:2]),-x[swaprows,3])
  • @BenBolker 这是一个好主意,并且确实会使代码更具可读性(并在重复启动相同的子集时节省一些不必要的时间)。好建议..
【解决方案2】:

您仍然可以使用ifelse,但由于您正在对相同的变量进行操作,因此您最好将 X1 和 X2 创建为 X4 和 X5 并最终删除它们。

x$X4<-x$X1
 x$X5<-x$X2
 x$X1<-with(x,ifelse(X1>X2,X2,X1))
 x$X2<-with(x,ifelse(X4>X2,X4,X2))
 x$X3<-with(x,ifelse(X4>X5,-X3,X3))
 x$X4<-NULL
 x$X5<-NULL
> x
   X1  X2    X3
1   4  10 -1440
2   4  10 -3765
3  10  22   523
4  10 295   730
5  10 295  1599
6  10 584  1872
7  10 403  1872
8  10 403  1872
9  10 281   554
10 10 123   554

【讨论】:

    猜你喜欢
    • 2016-09-28
    • 2021-12-11
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    • 2020-08-02
    相关资源
    最近更新 更多