Вычитание пар столбцов на основе соответствующих имен переменных с использованием цикла for (в R) - PullRequest
0 голосов
/ 02 сентября 2018

У меня есть широкоформатный фрейм данных, который содержит имена переменных, такие как "per601.199003" (все они начинаются с "per", за которыми следуют 3-4 цифры, точка останова . и число, обозначающее определенную дату) .

Теперь для каждой пары переменных "per601..." и "per602..." мне нужно вычесть последнюю из первой: "per601..." - "per602...".

Есть соответствующие окончания (например, "per601.199003" и "per602.199003"), но есть и другие окончания, у меня есть только "per601..." - или "per602..." -версия.

Для репродуцируемости, а также для простоты, скажем, это два моих списка имен переменных (я получил их, используя grep()). В действительности оба списка, очевидно, намного длиннее.

vars_601 <- c("per601.199003", "per601.200201", "per601.2001409")
vars_602 <- c("per602.199003", "per602.200201", "per602.2001702")

Теперь мне нужно что-то вроде этого:

for (i in per_601_list) {
  #search corresponding item in per_602_list (i.e. same ending)
  #subtract this latter item from the first item
}

1 Ответ

0 голосов
/ 02 сентября 2018

Я не знаю, какими должны быть ваши per_60x_list, поэтому позвольте мне использовать векторы символов имен столбцов:

vars_601 <- c("per601.199003", "per601.200201", "per601.2001409")
vars_602 <- c("per602.199003", "per602.200201", "per602.2001702")

И мне нужны примеры данных для работы, поэтому я создам кадр данных с именем df с такими именами:

df <- as.data.frame(matrix(sample(1:100, 60, T), 10, 6))
names(df) <- c(vars_601, vars_602)

Теперь для вашей петли. Сначала мы проверяем, есть ли соответствующий столбец 602 для каждого столбца 601, используя grep, и если это так, мы вычитаем и присваиваем новую переменную, используя df[paste()]:

for(i in seq_along(vars_601)) {
    # get the i'th 601 date
    thisdate <- substr(vars_601[i], 8, nchar(vars_601[i]))

    # check if there is a matching 602 date
    ismatch <- sum(grepl(paste0("*", thisdate), vars_602)) > 0

    # if there's a match, subtract: diff.date = 601.date - 602.date
    if(ismatch) {
        df[paste0("diff.", thisdate)] <- df[paste0("per601.", thisdate)] - 
                                         df[paste0("per602.", thisdate)]
    }
}

В качестве альтернативы и без зацикливания просто получите соответствующие 601 столбец в одном кадре данных, соответствующие 602 столбца в другом кадре данных и (убедившись, что столбцы находятся в правильном порядке) вычтите два кадра данных:

var_601_dates <- substr(vars_601, 8, 14)
var_602_dates <- substr(vars_602, 8, 14)

df[ , sort(vars_601[var_601_dates %in% var_602_dates])] - 
df[ , sort(vars_602[var_602_dates %in% var_601_dates])]
...