如何从前一行的值中减去一列的值,r中的不同列
how to subtract a value from one column from a value from a previous row, different column in r
我有一个由 3 列和 ~2000 行组成的数据框。
ID DistA DistB
1 100 200
2 239 390
3 392 550
4 700 760
5 770 900
第一列 (ID) 是每行的唯一标识符。我希望我的脚本读取每一行,并且 subtract/compare 每一行中 "DistA" 列的值来自上一行的 "DistB" 列的值。如果任何后续对的距离差<40,则输出它们在同一区域。
例如:在上面比较第 2 行和第 1 行的示例中,第 2 行的“239”和第 1 行的“200”小于 40,因此位于同一区域。同理2和3,在同一个区域,即2和2<40的区别。但是第 3 行和第 4 行不是因为相差 150.
我没能走多远,因为我卡在了比较(subtraction/difference)步骤。我试图编写一个循环来遍历所有行,但我不断收到错误。我什至应该使用循环,还是可以不使用循环来执行此操作?
我是新的 R 学习者,这是我目前拥有的 'rookie' 代码。我哪里错了。提前致谢:
#the function to compare the two columns
funct <- function(x){
for(i in 1:(nrow(dat)))
(as.numeric(dat$DistA[i-1])) - (as.numeric(dat$DistB[i]))}
#creating a new column 'new2' with the differences
dat$new2 <- apply(dat[,c('DistB','DistA')]),1, funct
当我运行这个时,我得到以下错误:
Error: unexpected ',' in "dat$new2 <- apply(dat[,c('DistB','DistA')]),"
我会感谢所有 comments/suggestions。
我相信 dplyr 可以帮到你。
library(dplyr)
dfData <- data.frame(ID = c(1, 2, 3, 4, 5),
DistA = c(100, 239, 392, 700, 770),
DistB = c(200, 390, 550, 760, 900))
dfData <- mutate(dfData, comparison = DistA - lag(DistB))
这导致...
dfData
ID DistA DistB comparison
1 1 100 200 NA
2 2 239 390 39
3 3 392 550 2
4 4 700 760 150
5 5 770 900 10
然后您可以检查某行是否与上一行 "area" 在同一行内。
我们也可以尝试 data.table
(类似于@David Arenburg 评论中建议的方法)。 shift
是devel
版本引入的新功能,默认为type='lag'
。它可以从 here
安装
library(data.table)#data.table_1.9.5
setDT(df1)[, Categ := c('Diff', 'Same')[
(abs(DistA-shift(DistB)) < 40 )+1L]][]
# ID DistA DistB Categ
#1: 1 100 200 NA
#2: 2 239 390 Same
#3: 3 392 550 Same
#4: 4 700 760 Diff
#5: 5 770 900 Same
如果我们同时需要 'difference' 和 'category' 列
setDT(df1)[,c('Dist', 'Categ'):={tmp= abs(DistA-shift(DistB))
list(tmp, c('Diff', 'Same')[(tmp <40)+1L])}]
df1
# ID DistA DistB Dist Categ
#1: 1 100 200 NA NA
#2: 2 239 390 39 Same
#3: 3 392 550 2 Same
#4: 4 700 760 150 Diff
#5: 5 770 900 10 Same
我有一个由 3 列和 ~2000 行组成的数据框。
ID DistA DistB
1 100 200
2 239 390
3 392 550
4 700 760
5 770 900
第一列 (ID) 是每行的唯一标识符。我希望我的脚本读取每一行,并且 subtract/compare 每一行中 "DistA" 列的值来自上一行的 "DistB" 列的值。如果任何后续对的距离差<40,则输出它们在同一区域。 例如:在上面比较第 2 行和第 1 行的示例中,第 2 行的“239”和第 1 行的“200”小于 40,因此位于同一区域。同理2和3,在同一个区域,即2和2<40的区别。但是第 3 行和第 4 行不是因为相差 150.
我没能走多远,因为我卡在了比较(subtraction/difference)步骤。我试图编写一个循环来遍历所有行,但我不断收到错误。我什至应该使用循环,还是可以不使用循环来执行此操作?
我是新的 R 学习者,这是我目前拥有的 'rookie' 代码。我哪里错了。提前致谢:
#the function to compare the two columns
funct <- function(x){
for(i in 1:(nrow(dat)))
(as.numeric(dat$DistA[i-1])) - (as.numeric(dat$DistB[i]))}
#creating a new column 'new2' with the differences
dat$new2 <- apply(dat[,c('DistB','DistA')]),1, funct
当我运行这个时,我得到以下错误:
Error: unexpected ',' in "dat$new2 <- apply(dat[,c('DistB','DistA')]),"
我会感谢所有 comments/suggestions。
我相信 dplyr 可以帮到你。
library(dplyr)
dfData <- data.frame(ID = c(1, 2, 3, 4, 5),
DistA = c(100, 239, 392, 700, 770),
DistB = c(200, 390, 550, 760, 900))
dfData <- mutate(dfData, comparison = DistA - lag(DistB))
这导致...
dfData
ID DistA DistB comparison
1 1 100 200 NA
2 2 239 390 39
3 3 392 550 2
4 4 700 760 150
5 5 770 900 10
然后您可以检查某行是否与上一行 "area" 在同一行内。
我们也可以尝试 data.table
(类似于@David Arenburg 评论中建议的方法)。 shift
是devel
版本引入的新功能,默认为type='lag'
。它可以从 here
library(data.table)#data.table_1.9.5
setDT(df1)[, Categ := c('Diff', 'Same')[
(abs(DistA-shift(DistB)) < 40 )+1L]][]
# ID DistA DistB Categ
#1: 1 100 200 NA
#2: 2 239 390 Same
#3: 3 392 550 Same
#4: 4 700 760 Diff
#5: 5 770 900 Same
如果我们同时需要 'difference' 和 'category' 列
setDT(df1)[,c('Dist', 'Categ'):={tmp= abs(DistA-shift(DistB))
list(tmp, c('Diff', 'Same')[(tmp <40)+1L])}]
df1
# ID DistA DistB Dist Categ
#1: 1 100 200 NA NA
#2: 2 239 390 39 Same
#3: 3 392 550 2 Same
#4: 4 700 760 150 Diff
#5: 5 770 900 10 Same