如何根据R中其他列中的数据有条件地执行减法?

时间:2019-11-27 15:16:09

标签: r for-loop

我有一个数据集,我在这里计算基因之间的距离。这涉及从当前行的“ bp.snp”列减去下面一个基因行的“ bp.snp”列,以得出当前行/基因与下一个基因行的距离。

但是我不希望每次进行新染色体减法时,如何在我的for循环中解决这个问题?

我的数据如下:

Gene  Chromosome  bp.snp  
ACE        1        1   
NOTCH      1        2   
BRCA       1        3   
HER        2       7000 
GABA       2       7001  
P53        3       20000 
APX1       3       20001 

我希望输出列看起来像这样:

Gene  Chromosome  bp.snp   distance
ACE        1        1         1
NOTCH      1        2         1
BRCA       1        3         0/NA
HER        2       7000       1
GABA       2       7001       0/NA
P53        3       20000      1
APX1       3       20001      1

因此,它忽略了每次染色体改变时执行bp.snp减法的操作。

我的代码当前是这样:

df$distance <- NA
for(i in 1:(nrow(df) - 1)) {
  df$distance[i] = df$bp.snp1[i+1] - df$bp.snp1[i]}

我不确定如何从本质上开始要求代码执行“每当染色体列增加1时,就不会在循环中执行减法”

2 个答案:

答案 0 :(得分:1)

假设bn.snp处于升序:

do.call('rbind', lapply(split(df, df$Chromosome), function(x) { x$distance <- c(diff(x$bp.snp), 0); return(x) }))

编辑:似乎您要的是“到下一个的距离”而不是“与上一个的距离”

答案 1 :(得分:1)

您可以使用avediff来计算Chromosome中的距离。

df$distance  <- ave(df$bp.snp, df$Chromosome, FUN=function(x) c(diff(x), NA))
df
#   Gene Chromosome bp.snp distance
#1   ACE          1      1        1
#2 NOTCH          1      2        1
#3  BRCA          1      3       NA
#4   HER          2   7000        1
#5  GABA          2   7001       NA
#6   P53          3  20000        1
#7  APX1          3  20001       NA

或者您只计算所有差异,并将NA上有差异的地方设置为Chromosome

df$distance <- c(diff(df$bp.snp), NA)
df$distance[c(diff(df$Chromosome) > 0, FALSE)]  <- NA
#   Gene Chromosome bp.snp distance
#1   ACE          1      1        1
#2 NOTCH          1      2        1
#3  BRCA          1      3       NA
#4   HER          2   7000        1
#5  GABA          2   7001       NA
#6   P53          3  20000        1
#7  APX1          3  20001       NA