我在这里的前一个问题中有这个函数
shift <- function(d, k) rbind( tail(d,k), head(d,-k), deparse.level = 0 )
Run Code Online (Sandbox Code Playgroud)
此函数将数据框d旋转K,这意味着它将从数据框的末尾开始占用K行并将它们放在顶部.
我想创建相同的函数(使用相同的语言),但不使用R预制函数(head,tail,...),但只使用编程基础.(for,...)
怎么做到这一点?
好吧,我不知道你的意思,without using R functions因为几乎所有东西都是R函数,但这里只是一个解决方案,只使用非常通用的nrow()(矩阵的行数),%%(模数)和seq_len(相当于1:length(x)除了它更好的工作) ):
m <- matrix(1:40,,2,byrow=TRUE)
shift2 <- function(d, k) d[(seq_len(nrow(d))-k-1)%%(nrow(d))+1,]
shift2(m,5)
[,1] [,2]
[1,] 31 32
[2,] 33 34
[3,] 35 36
[4,] 37 38
[5,] 39 40
[6,] 1 2
[7,] 3 4
[8,] 5 6
[9,] 7 8
[10,] 9 10
[11,] 11 12
[12,] 13 14
[13,] 15 16
[14,] 17 18
[15,] 19 20
[16,] 21 22
[17,] 23 24
[18,] 25 26
[19,] 27 28
[20,] 29 30
Run Code Online (Sandbox Code Playgroud)
如果你的意思是"普通编程代码"它不应该被矢量化,那么,你正在以正确的方式学习错误的语言或以错误的方式学习正确的语言.每当你想出一个矢量化的解决方案而不是for循环时,你很高兴在R.
但是,如果你真的想用循环来做这个,那么unvectorized的功能完全相同:
shift3 <- function(d, k)
{
out <- matrix(,nrow(d),ncol(d))
sorts <- (seq_len(nrow(d))-k-1)%%(nrow(d))+1
for (i in seq_len(nrow(d))) out[i,] <- d[sorts[i],]
return(out)
}
Run Code Online (Sandbox Code Playgroud)
证明他们都是平等的:
all(shift(m,5) == shift2(m,5) & shift2(m,5) == shift3(m,5))
[1] TRUE
Run Code Online (Sandbox Code Playgroud)
实际上shift3(),STILL包含了很多矢量化,显示了R中的原生.这是一个完全非版本化的版本:
shift3 <- function(d, k)
{
out <- matrix(,nrow(d),ncol(d))
sor <- numeric(1)
for (i in seq_len(nrow(d)))
{
if (i-k < 1) sor <- nrow(d)-k+i else sor <- i-k
for (j in seq_len(ncol(d))) out[i,j] <- d[sor,j]
}
return(out)
}
Run Code Online (Sandbox Code Playgroud)