比R中的嵌套循环更有效

时间:2018-01-30 00:31:24

标签: r for-loop apply

我试图通过使用for来打破apply循环的习惯,但我已经被这个问题困住了。我有一个for循环,它将每两行折叠成一行对象obj.tmp(366乘34343),但它很慢。

这是一个缩短的例子:

df <- data.frame(X1 = letters[1:10], X2 = letters[11:20], stringsAsFactors = FALSE)  

因此:

> df
X1 X2
a  k
b  l
c  m
d  n
e  o
f  p
g  q
h  r
i  s
j  t

for(i in 1:(nrow(df)/2)){
  df2[i,] <- apply( df[(i*2-1):(i*2),], 2, paste, collapse = "")
}

输出:

> df2 
X1  X2
ab  kl
cd  mn
ef  op
gh  qr
ij  st

关于更好方法的建议?

3 个答案:

答案 0 :(得分:1)

根据您的样本数据,这是一种可能性:

# Sample data
df <- data.frame(X1 = letters[1:10], X2 = letters[11:20], stringsAsFactors = FALSE);

do.call(rbind, lapply(split(df, gl(nrow(df) / 2, 2, nrow(df))), function(x) sapply(x, paste0, collapse = "")))
#  X1   X2
#1 "ab" "kl"
#2 "cd" "mn"
#3 "ef" "op"
#4 "gh" "qr"
#5 "ij" "st"

说明:每两行拆分df并按列存储listpaste个条目,并将rbind存储到最终对象中。

如果您想避免rbind list元素,您也可以这样做:

t(sapply(split(df, gl(nrow(df) / 2, 2, nrow(df))), function(x) sapply(x, paste0, collapse = "")));
#  X1   X2
#1 "ab" "kl"
#2 "cd" "mn"
#3 "ef" "op"
#4 "gh" "qr"
#5 "ij" "st"

答案 1 :(得分:1)

我们可以使用aggregate函数:

df1=cbind(df,id=rep(1:(nrow(df)/2)# Create a new df with an id that shows the rows to be combined
aggregate(.~id,df1,each=2)),paste0,collapse="")[-1]#Combine the rows

  X1 X2
1 ab kl
2 cd mn
3 ef op
4 gh qr
5 ij st

你可以在一行中完成所有这些:

  aggregate(.~id,cbind(df,id=rep(1:(nrow(df)/2),each=2)),paste0,collapse="")[-1]

您也可以尝试:

matrix(do.call(paste0,data.frame(matrix(unlist(df),,2,T))),,2)
     [,1] [,2]
[1,] "ab" "kl"
[2,] "cd" "mn"
[3,] "ef" "op"
[4,] "gh" "qr"
[5,] "ij" "st"

答案 2 :(得分:0)

这样的事情?如果不是,你能更清楚吗?并传递代码来复制您正在做的事情。但我希望这能解决你的问题。

df <- data.frame(X1 = letters[1:10], stringsAsFactors = FALSE)
df2 <- data.frame(X1 = character(), stringsAsFactors = FALSE)

sapply(1:round(nrow(df)/2), FUN = function(x) {
  df2[x,] <<- paste(df[(x*2-1):(x*2),], collapse = "")
})
df2