使用另一个数据帧的信息提取数据框中组内的间隔。

时间:2012-09-06 07:28:22

标签: r dataframe plyr

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

我的意见:

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 )])

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

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

抱歉英语不好。

1 个答案:

答案 0 :(得分:3)

首先,您的数据:

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 >= 0
  3. x值不高于阈值(df1$x <= as.numeric(a[2])
  4. 注意:值a[2]需要通过as.numeric转换为数字。这是必要的,因为df2中的主题id表示为字符,从而apply将整行(包括阈值)转换为字符。

    这些标准中的每一个都返回逻辑向量。这些向量与&组合成一个逻辑向量,指示是否所有三个标准都已满。使用df1[logical.vector, ]选择逻辑向量为df1的所有TRUE行。由于,后未指定任何内容,因此会选择所有列。

    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返回的列表中的两个数据帧都会合并。