【问题标题】:R function to subset dataframe so that non-adjacent values in a column differ by >= X (starting with the first value)R函数对数据框进行子集化,以便列中的非相邻值相差> = X(从第一个值开始)
【发布时间】:2020-10-15 13:44:50
【问题描述】:

我正在寻找一个函数,它遍历数据框中给定列的行(“pos”表示位置,升序),并且只保留那些值至少有 10 个不同的行,从第一个开始row.因此它将从第一行开始(并存储它),然后继续直到找到一个值至少比第一行高 10 的行,存储该行,然后再次从该值开始寻找下一个>10diff 一个。

到目前为止,我有一个 R for 循环,它成功地找到了至少相隔 X 值的相邻行,但它没有能力向下看一行,也没有能力在找到给定行并开始后停止再次从那里。

这是我拥有的功能:

# example data frame     
df <- data.frame(x=c(1:1000), pos=sort(sample(1:10000, 1000)))

# prep function (this only checks row above)
library(dplyr)
pos.apart.subset <-  function(df, pos.diff) {
  # create new dfs to store output
  new.df <- list()
  new.df1 <- data.frame()
  # iterate through each row of df
  for (i in 1:nrow(df)) {
    # if the value of next row is higher or equal than value or row i+posdiff, keep
    # if not ascending, keep
    # if first row, keep
    if(isTRUE(df$pos[i+1] >= df$pos[i]+pos.diff | df$pos[i+1] < df$pos[i] | i==1 )) {
      # add rows that meet conditions to list
      new.df[[i]] <- df[i,] }
  }
  # bind all rows that met conditions
  new.df1 <- bind_rows(new.df)
  return(new.df1)}

# test run for  pos column adjacent values to be at least 10 apart 
df1 <- pos.apart.subset(df, 10); head(df1)

很高兴在 awk 或任何其他语言中执行此操作。非常感谢。

【问题讨论】:

    标签: r loops dataframe subset


    【解决方案1】:

    看来我之前误解了这个问题,因为我们不想计算连续行之间的差异,你可以试试:

    nrows <- 1
    previous_match <- 1
    for(i in 2:nrow(df)) {
      if(df$pos[i] - df$pos[previous_match] > 10) {
        nrows <- c(nrows, i)
        previous_match <- i
       }
     }
    

    然后对选定的行进行子集化:

    df[nrows, ]
    

    较早的答案

    我们可以使用diff获取连续行之间的差值,并选择差值大于10的行。

    head(subset(df, c(TRUE, diff(pos) > 10)))
    
    #    x pos
    #1   1   1
    #2   2  31
    #6   6  71
    #9   9 134
    #10 10 151
    #13 13 185
    

    第一个TRUE默认选择第一行。

    dplyr 中,我们可以使用lag 从上一行获取值:

    library(dplyr)
    df %>% filter(pos - lag(pos, default = -Inf) > 10)
    

    【讨论】:

    • 您好,感谢您的回答。问题是我不只是想抓取差异大于 10 的连续行,我想抓取与第一行相差超过 10 的任何行,然后将超过 10 到第二个选定行,这些不太可能是连续的。所以像累积差异这样的东西可能会起作用(不过感谢你的想法,越来越近了)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多