【问题标题】:Extract intervals inside groups in a dataframe , using information of another dataframe .使用另一个数据帧的信息提取数据帧中组内的间隔。
【发布时间】:2012-09-06 07:28:21
【问题描述】:

正如我在标题中所说,我的目的是使用另一个数据帧的信息来提取我的数据帧子集的间隔。

我的意见:

df1:

  subject         x      y
7G001-0024-10   0,00    15
7G001-0024-10   97,29   18
7G001-0024-10   197,34  21
7G001-0024-10   314,66  22
7G001-0024-10   482,77  25
7G001-0030-10   0,00    12
7G001-0030-10   99,50   16
7G001-0030-10   184,37  20
7G001-0030-10   301,89  25
7G001-0030-10   585,67  27
     ...         ...   ...

df2:

    subject   Threshold 
7G001-0024-10   177,08
7G001-0030-10   385,13
    ...          ...

对于每个主题,我想在 df1 中提取 0 和每个主题的阈值之间的 x 和 y 数据包含在 df2 中,以获得这种精神的输出:

  subject         x      y
7G001-0024-10   0,00    15
7G001-0024-10   97,29   18
7G001-0030-10   0,00    12
7G001-0030-10   99,50   16
7G001-0030-10   184,37  20
7G001-0030-10   301,89  25
    ...          ...   ...

我的第一个想法是在 ddply 函数中使用 which() :

break=ddply(df1,.(subject),summarize,fun=x[which(x>=0 & x<Threshold )])

但我被卡住了,我没有看到如何在 which 函数中指示我的阈值 (df2) 的变化。

好吧,如果有人能告诉我如何处理它(我的第一个直觉与否)

对不起英语不好。

【问题讨论】:

    标签: r dataframe plyr


    【解决方案1】:

    首先,您的数据:

    df1 <- read.table(text = "subject         x      y
    7G001-0024-10   0,00    15
    7G001-0024-10   97,29   18
    7G001-0024-10   197,34  21
    7G001-0024-10   314,66  22
    7G001-0024-10   482,77  25
    7G001-0030-10   0,00    12
    7G001-0030-10   99,50   16
    7G001-0030-10   184,37  20
    7G001-0030-10   301,89  25
    7G001-0030-10   585,67  27", header = TRUE, dec = ",")
    
    df2 <- read.table(text = "subject   Threshold 
    7G001-0024-10   177,08
    7G001-0030-10   385,13", header = TRUE, dec = ",")
    

    你可以使用简单的apply来解决任务:

    do.call("rbind", apply(df2, 1, FUN = function(a) {df1[a[1] == df1$subject & df1$x >= 0 & df1$x <= as.numeric(a[2]), ]}))
    
    #         subject      x  y
    # 1 7G001-0024-10   0.00 15
    # 2 7G001-0024-10  97.29 18
    # 6 7G001-0030-10   0.00 12
    # 7 7G001-0030-10  99.50 16
    # 8 7G001-0030-10 184.37 20
    # 9 7G001-0030-10 301.89 25
    

    它是如何工作的?

    首先,函数apply(df2, 1, FUN) 对数据框df2 中的每一行应用一个函数。值1 表示该函数应用于对象的第一个维度(第二个维度是列)。

    看看一个简单的函数。它只返回df2 的第一行和第二行。请注意,在输出中,行按列排列。

    > apply(df2, 1, FUN = function(a) a)
              [,1]            [,2]           
    subject   "7G001-0024-10" "7G001-0030-10"
    Threshold "177.08"        "385.13"   
    

    由于我们要提取df1 的子集,因此需要更复杂的函数。所以,我指定:

    FUN = function(a) {df1[a[1] == df1$subject & df1$x >= 0 & df1$x <= as.numeric(a[2]), ]}
    

    在此函数中,a 表示数据框df2 的一行。此函数应用了两次,一次用于df2 的两行。 a[1]是主题号,a[2]是对应的阈值。 该函数通过三个标准提取数据框df1的行子集:

    1. 主题相同 (a[1] == df1$subject)
    2. x 值至少为零 (df1$x &gt;= 0)
    3. x 值不高于阈值 (df1$x <= as.numeric(a[2]))

    注意:a[2] 的值需要通过as.numeric 转换为数字。这是必要的,因为 df2 中的主题 ID 表示为字符,因此 apply 将整行(包括阈值)转换为字符。

    这些条件中的每一个都返回一个逻辑向量。这些向量与&amp; 组合成一个逻辑向量,指示是否满足所有三个条件。使用df1[logical.vector, ] 选择逻辑向量为TRUEdf1 的所有行。由于, 之后没有指定任何内容,因此选择了所有列。

    df1 的所有三个条件都满足的行由apply 函数返回。

    > apply(df2, 1, FUN = function(a) {df1[a[1] == df1$subject & df1$x >= 0 & df1$x <= as.numeric(a[2]), ]})
    [[1]]
            subject     x  y
    1 7G001-0024-10  0.00 15
    2 7G001-0024-10 97.29 18
    
    [[2]]
            subject      x  y
    6 7G001-0030-10   0.00 12
    7 7G001-0030-10  99.50 16
    8 7G001-0030-10 184.37 20
    9 7G001-0030-10 301.89 25
    

    函数apply返回一个包含两个数据框的列表,每行一个对应df2

    最后一步,将列表中的数据框合并为一个数据框。函数do.call("rbind", list) 执行函数rbind 并将列表中的参数传递给它。对于长度为 2 的列表,这相当于 rbind(list[[1]], list[[2]])。这样apply返回的列表中的两个数据框就合并了。

    【讨论】:

    • 非常感谢您的回答,一切正常!如果不是太多问你能评论你的代码吗?提前致谢。
    • 我用附加部分更新了我的答案(“它是如何工作的?”)。
    猜你喜欢
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 2021-05-07
    • 2016-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多