嵌套用于循环和列重命名

时间:2014-02-09 18:17:58

标签: r

如何根据嵌套for循环中其他列的条件重命名列?

我正试图在R:中做到这一点 如果名为A1的列不为空且列A2Akk是某个数字)为空,则将列B2...Bk重命名为B1_1...B1_k }

我数据的简化示例:

A1  B1  A2  B2  A3  B3  A4  B4

1    1      2       3       4

a    b      d       c   e   f 

基本概念是,如果Aj为空,则相应的B条目“属于”前一列索引A[j-1],因此需要重命名。

我知道这些列的位置是这样的,当我尝试这样做时,我在数据帧中使用了它们的位置。下面的代码是我正在考虑做的事情但是我不太了解R语法并且无法使用任何东西:

for (k in 1:20){
for (j in 1:600){
for (i in 0:90) {

  if (df[j,2*i]!="" && df[j,2*i+2*k]=="") {B[i+1_[i+1]]=df[j,1+2*i+2*k]}

}}}

我在stackoverflow上看了一些类似的帖子,但我是新手并且不了解大部分内容。

1 个答案:

答案 0 :(得分:0)

注意B1_1...B1_k需要缩短一个元素,例如B1_1..B1_k-1

df1 <- data.frame(
    A1=c(1, "a"),
    B1=c(1, "b"),
    A2=c("", ""),
    B2=c(2, "d"),
    A3=c("", ""),
    B3=c(3, "c"),
    A4=c("", "e"),
    B4=c(4, "f"))
### get columns which are Empty 
Es <- colnames(df1)[sapply(1:ncol(df1), function(x) all((df1[x])=="") )]
### find largest no. following A in these empties
k1 <- max(as.integer(gsub("A", "", Es)))
### replace colums B2..Bk with B1_1...Bk-1
colnames(df1)[grepl("B", colnames(df1))][2:k1] <- paste0("B1_",seq(k1)[-k1])
> df1
  A1 B1 A2 B1_1 A3 B1_2 A4 B4
1  1  1       2       3     4
2  a  b       d       c  e  f

编辑这样吗?

### get columns with at least one empty cell
### same as above but replace `all` with `any`
Es <- colnames(df1)[sapply(1:ncol(df1), function(x) any((df1[x])=="") )]
### find largest no. following A in these empties
k1 <- max(as.integer(gsub("A", "", Es)))
### new data frame with columns B2...Bk
df2 <- df1[grepl("B", colnames(df1))][2:k1]
### rename
colnames(df2) <- paste0("B1_",seq(k1)[-k1])
> (cbind(df1, df2))
  A1 B1 A2 B2 A3 B3 A4 B4 B1_1 B1_2 B1_3
1  1  1     2     3     4    2    3    4
2  a  b     d     c  e  f    d    c    f

这种生成新data.frame然后cbind的方法并不具有内存效率,但这对于小尺寸来说并不重要,我认为它使代码更容易阅读。

这是一种data.table方法,可以避免内存中的重复,因此对大型集合非常有用:

library(data.table)
dt1 <- as.data.table(df1)
### get k1 as above
### get columns B2...Bk
Bs <- paste0("B", seq(k1)[-1])
### add/assign duplicated columns with new column names using :=
> (dt1[, paste0("B1_",seq(k1)[-k1]) := dt1[, Bs, with=FALSE] ])
   A1 B1 A2 B2 A3 B3 A4 B4 B1_1 B1_2 B1_3
1:  1  1     2     3     4    2    3    4
2:  a  b     d     c  e  f    d    c    f