如何在R中批量处理前缀名称相同的列
我有一个名为“test”的数据框,如下所示如何在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
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函数,但我想试一试。