使用for循环(在R中)基于相应的变量名减去列对

问题描述 投票:0回答:1

我有一个宽格式的数据框,包含变量名称,如"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
}
r for-loop subtraction
1个回答
1
投票

我不知道你的per_60x_lists应该是什么,所以让我只使用列名的字符向量:

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)

现在为你的循环。我们首先使用grep检查每个601列是否有相应的602列,如果是,我们使用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])]
© www.soinside.com 2019 - 2024. All rights reserved.