2014-02-09 2 views
0

Как переименовать столбцы на основе условий в других столбцах в вложенных циклах?Переплетение вложенных циклов и столбцов

Я пытаюсь сделать это в R:
Если столбец с именем A1 не является пустым и столбцы A2 через Ak (k некоторое число) являются пустыми, то переименовывать столбцы 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 «принадлежит» previ ous index A[j-1] и поэтому его нужно переименовать.

Я знаю, где расположены позиции этих столбцов, когда я пытался это сделать, я использовал их положение в dataframe. Приведенный ниже код является то, что я думаю делать, но я не знаю, очень много синтаксиса 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, но я м новичок и не понимал большую часть этого.

+0

вы можете предоставить соответствующий вопрос? – xlembouras

+0

@xlembouras Я добавил общий вопрос к вершине. Извините, если на моем посту не ясно, что я прошу. – user3235

+0

С какой целью? Имена столбцов ** не **, которые вы хотите тестировать для содержимого указанных столбцов. Забудьте о конструкции 'for' - есть более простые способы - но сообщите нам, чего вы пытаетесь достичь. –

ответ

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 Ing не против памяти эффективной, но это не имеет значения много для небольших размеров, и я думаю, что это делает легче читать код.

Вот 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 
+0

Можно ли создать новый столбец для B1_1 и оставить старый B_2? И тогда можно было бы рассмотреть пустоту в каждом ряду? Значение B4 будет B1_3. – user3235

+0

Отличное спасибо! – user3235

Смежные вопросы