【问题标题】:compare multiple values with multple values in R Dataframe将多个值与 R Dataframe 中的多个值进行比较
【发布时间】:2020-05-03 09:33:22
【问题描述】:

我有一个包含 2 列“时间”和“a”的数据框。

df <- data.frame(time = c(1, 2, 3, 4, 5, 6, 7, 8, 9), a = c(3, 8, 2, 2, 2, 2, 2, 4, 5))

如果值随时间变化,如何进行比较?我需要数据框中的新列“comp”,显示列“c”中的第三个值是否仍与同一列中的最后两个值和之前的两个值相同。所以结果可能是这样的:

df <- data.frame(time = c(1, 2, 3, 4, 5, 6, 7, 8, 9), a = c(3, 8, 2, 2, 2, 2, 2, 4, 5), comp = c(F, F, F, F, T, F, F, F, F)

最后我需要比较一个大约 3 mio 的列。观察。

【问题讨论】:

    标签: r dataframe compare match


    【解决方案1】:

    使用 tidyverse:

    library(tidyverse)
    
    df %>% 
      arrange(time) %>% 
      mutate(comp = a == lag(a) & a == lag(a, 2) & a == lead(a) & a == lead(a, 2))
    
    #   time a  comp
    # 1    1 3 FALSE
    # 2    2 8 FALSE
    # 3    3 2 FALSE
    # 4    4 2 FALSE
    # 5    5 2  TRUE
    # 6    6 2 FALSE
    # 7    7 2 FALSE
    # 8    8 4 FALSE
    # 9    9 5 FALSE
    

    【讨论】:

    • 又好又简单的解决方案 :) 如果我想比较特定值怎么办。例如,如果有两个没有改变的(比如在我的 df 示例中)或(作为条件)六个,结果才为 True?
    • 你可以一直在comp = ...语句的右边添加条件,比如&amp; a == 2
    【解决方案2】:

    使用data.table@Bas 的类似解决方案

    library(data.table)
    setDT(df)[, comp := a == shift(a) & a == shift(a, 2) & 
                      a == shift(a, type = 'lead') & a == shift(a, 2, type = 'lead')]
    
    #   time a  comp
    #1:    1 3 FALSE
    #2:    2 8 FALSE
    #3:    3 2 FALSE
    #4:    4 2 FALSE
    #5:    5 2  TRUE
    #6:    6 2 FALSE
    #7:    7 2 FALSE
    #8:    8 4 FALSE
    #9:    9 5 FALSE
    

    【讨论】:

    • 感谢您的 data.table 解决方案!如果我想检查例如接下来的 20 个值怎么办?一定有比写shift(a, 1)shift(a, 2) 等更好的解决方案...因为如果我尝试setDT(df)[, comp := a == shift(a, type = "lag", n = c(1:2)) &amp; a == shift(a, type = "lead", n = c(1:2))] 我会收到错误:'list' object cannot be coerced to type 'double'
    • 可以使用滚动操作。查看zoos ?rolapply 函数。如果您在为您的数据实施时遇到问题,您可以提出一个新问题。
    【解决方案3】:

    如果我理解正确,您正在寻找与其两侧相邻的 2 个值相同的值,在这种情况下,您很乐意忽略第 2 个和最后 2 个的“缺失”相邻值价值观。

    使用基础 R:

    sameasadj=function(v,n=2,include_ends=T) {
        if(include_ends){vv=c(rep(head(v,1),n),v,rep(tail(v,1),n))} 
        else {vv=c(rep(NA,n),v,rep(NA,n))}
        sapply(seq_along(v),function(i) diff(range(vv[i:(i+2*n)]))==0)
    }
    
    df$comp = sameasadj(df$a)
    df$comp
    

    输出:

    [1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
    

    解释:

    sameasadj=function(v,n=2,include_ends=T) = 定义函数 sameasadj 来测试每个值是否与每侧相邻的相邻值相同。我们可以选择相邻邻居的数量 n (在您的情况下为 2),以及是否包括末端(或为这些末端返回“NA”,因为它们的一侧缺少足够的邻居)。

    if(include_ends){vv=c(rep(head(v,1),n),v,rep(tail(v,1),n))} = 如果我们想包括末端,那么我们只需添加“缺失”的邻居,以便它们匹配

    else {vv=c(rep(NA,n),v,rep(NA,n))} = 否则我们添加 'NA' 值

    sapply(seq_along(v),function(i) = 沿着向量中的每个位置 i...

    diff(range(vv[i:(i+2*n)]))==0) = ...并检查从i到i+2*n的元素是否都相同(如果x的所有元素都相同,diff(range(x))==0将返回TRUE

    将它们全部放入一个函数中,以后可以很容易地改变你对相邻邻居的数量的想法,或者如何处理末端......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-21
      • 2019-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多