如何在R中批量处理前缀名称相同的列

如何在R中批量处理前缀名称相同的列,r,R,我有一个名为“test”的数据框,如下所示 Day Rain SWC_11 SWC_12 SWC_13 SWC_21 SWC_22 01/01/2019 00:00:00 0.0 51 60 63 60 64 02/01/2019 00:00:00 0.2 51.5 60.3 63.4 6

我有一个名为“test”的数据框,如下所示

Day                     Rain      SWC_11    SWC_12    SWC_13    SWC_21   SWC_22   
01/01/2019  00:00:00     0.0        51        60        63       60        64 
02/01/2019  00:00:00     0.2        51.5      60.3      63.4     60.8      64.4
03/01/2019  00:00:00     0.0        51.3      60.3      63.3     60.6      64.1 
04/01/2019  00:00:00     0.4        53        62        64       62        65   
05/01/2019  00:00:00     1.0        55        64        66       64        67
Day                     Rain   SWC_11_jump   SWC_12_jump    SWC_13_jump    SWC_21_jump   SWC_22_jump  
01/01/2019  00:00:00     0.0       0            0             0                 0            0
02/01/2019  00:00:00     0.2      0.5           0.3           0.4               0.8          0.4
03/01/2019  00:00:00     0.0       0            0             0                 0            0
04/01/2019  00:00:00     0.4      1.7           1.7           0.7               1.4          0.9
05/01/2019  00:00:00     1.0       2            2             2                 2            2
我想用一个循环函数来找到雨后SWC数据的跳跃,这有点像先找到非零的雨水数据,然后使用下一个SWC数据点减去当前的SWC数据点。现在的问题是,我有许多前缀为“SWC”的“SWC”列,如何用一个简单的循环函数来运行它们

预期的数据帧应如下所示

Day                     Rain      SWC_11    SWC_12    SWC_13    SWC_21   SWC_22   
01/01/2019  00:00:00     0.0        51        60        63       60        64 
02/01/2019  00:00:00     0.2        51.5      60.3      63.4     60.8      64.4
03/01/2019  00:00:00     0.0        51.3      60.3      63.3     60.6      64.1 
04/01/2019  00:00:00     0.4        53        62        64       62        65   
05/01/2019  00:00:00     1.0        55        64        66       64        67
Day                     Rain   SWC_11_jump   SWC_12_jump    SWC_13_jump    SWC_21_jump   SWC_22_jump  
01/01/2019  00:00:00     0.0       0            0             0                 0            0
02/01/2019  00:00:00     0.2      0.5           0.3           0.4               0.8          0.4
03/01/2019  00:00:00     0.0       0            0             0                 0            0
04/01/2019  00:00:00     0.4      1.7           1.7           0.7               1.4          0.9
05/01/2019  00:00:00     1.0       2            2             2                 2            2

我不是在循环功能,希望有人能帮助。谢谢。

在朋友们的帮助下,我终于找到了解决办法

# find target columns
target_colnames <- colnames(test)[which(grepl("SWC_", colnames(test)) == TRUE)]
output_colnames <- paste(target_colnames,"_jump",sep="")
test[output_colnames] <- NA

## if rain≠0, then use the next SWC data point subtract the current data point.
for (i in 1:(nrow(test)-1)){
for (j in 1:length(target_colnames)){
if (test$Rain[[i]] != 0){
test[output_colnames[j]][i,]  <- test[target_colnames[j]][i+1,] - 
test[target_colnames[j]][i,]
}
}
}
#查找目标列
target_colnames不迭代

R的力量在于同时处理多件事情。是的,水下工作是按顺序进行的,但R中按顺序进行的每一步都涉及大量的内存访问和数据移动。现在对于这个例子来说,这并不重要(假设你并不真正关心它是需要1ms还是10ms),但是一般来说,你会尽可能多地使用R的并行函数

在这里运行代码时要做的是,每次迭代都会重写整个data.frame。这意味着它被读取,一个数据点被改变,然后被写回内存。然后我们得到下一个迭代。但我们不需要每次计算都使用整个数据框,一列上的所有操作都可以独立于其他列进行

这意味着我们可以使用
apply
-函数。作为一个初学者,它可能看起来很吓人,但是一旦你习惯了它,你会发现它(以及它的近亲)非常强大,它使你的代码更加健壮。这也意味着你不需要初始化任何东西到
NA
,你只需要写下答案

稍后我们将编写
difference\u函数
,但将其输出如下:

output <- apply(test[,grepl("SWC_", colnames(test))], 2, difference_function)
名称
pmax
代表“平行最大值”,因此对于每个元素,它将取最大值(0,元素)。它将一次完成

最后:

您不必单独指定函数。如果你只想用一次,你可以直接给它申请

如果知道总共有多少列,可以直接分配给
test
,之后只需设置列名即可

test[,8:12] <- apply(test[3:7], 2, function(col) {
  pmax(0, col - c(Inf, col[-length(col)]))
})
colnames(test)[8:12] <- paste0(colnames(test)[grep('SWC', colnames(test))], '_jump')

test[,8:12]请显示预期的output@akrun我已经重新编辑了这个问题。请使用dplyr/tidyverse中的gather()将SWC列转换为单个列中的一个因子。您可以使用
paste0(“SWC”,x)
迭代SWC列。非常感谢您的明确解释。我最近在处理大数据帧时也发现了循环函数的问题。这相当耗时,而且进行得太慢。虽然直到现在我还没有使用apply函数,但我想试一试。