用于子集化的循环,在数据帧中用于另一个数据帧?

时间:2014-02-21 14:41:10

标签: r

我搜索了许多关于这个Subsetting a dataframe in R by multiple conditions的帖子,关于选择“which”函数来选择值dataframe dataframe并找不到其他解决方案。问题如下:

我有数千个案例的以下数据集:

> head(Datos)
   tipo         estacion     hora  usos
 1 hábil         A.SANIN      X4    11
 2 hábil        ALAMOS        X4     4
 3 hábil        AMANECER      X4    45
 4 hábil       AMERICAS       X4     2
 5 hábil       ATANASIO       X4    10
 6 hábil       BELALCAZAR     X4     5
 .    .                       .     .
 .    .                       .     .
 .    .                       .     .

上面数据框子集的变量是“usos”变量“tipo”取值:“hábil”,“Sábado”和“Festivo”。变量“estacion”有60个级别,变量“hora”有22个值:x4,x5,x6,... x23。由于我需要根据“tipo”,“estacion”和“hora”的所有组合计算四分位数,我使用“聚合”函数并计算临界值,所以我得到了这个:

  > head(todo)
    Group.1  Group.2      Group.3      y1    y2
 1   hábil      X4         A.SANIN      1.5   21.5
 2   Sábado     X4         A.SANIN      4.0   12.0
 3   Festivo    X4         A.SANIN      0.0   0.0
 4   hábil      X5         A.SANIN      66.0  130.0
 5   Sábado     X5         A.SANIN      40.0  96.0
 6   Festivo    X5         A.SANIN      7.5   43.5
 .                      .
 .                      .
 .                      .

每一行都是不同的情况,值y1和y2是我的临界值。需要根据数据帧“todo”的值y1和y2,我选择从数据帧“Datos”中得到小于y1或更大y2的变量“usos”。但在一个周期中,数据帧“todo”上有3480种组合,即3480行。并将其存储在另一个Matrix中。

例如,第一种情况如下:

print(which(subset(Datos$usos,Datos$tipo=="hábil"&Datos$hora=="X4"&Datos$estacion=="A.SANIN")<todo$y1[1] | subset(Datos$usos,Datos$tipo=="hábil"&Datos$hora=="X4"&Datos$estacion=="A.SANIN")>todo$y2[1]))

我需要对数据帧“all”的所有行执行此操作,并将其应用于“使用”数据帧“Data”。

谢谢!

1 个答案:

答案 0 :(得分:0)

我很难理解你在说什么,但我认为这就是你想要的。首先,将todoDatos合并:

# Rename the columns of todo to match Datos
names(todo)<-c('tipo','hora','estacion','y1','y2')
# Merge the two.
Datos.y.todo<-merge(Datos,todo)

现在,您可以根据自己的标准轻松进行分组:

with(Datos.y.todo, Datos.y.todo[usos<y1 | usos>y2, ])

我相信以上回答了你的问题。让我用你的数据来说明。

# Load in your data.
Datos<-read.table(textConnection('tipo         estacion     hora  usos
1 hábil         A.SANIN      X4    11
2 hábil        ALAMOS        X4     4
3 hábil        AMANECER      X4    45
4 hábil       AMERICAS       X4     2
5 hábil       ATANASIO       X4    10
6 hábil       BELALCAZAR     X4     5'),header=TRUE)

todo<-read.table(textConnection('Group.1  Group.2      Group.3      y1    y2
1   hábil      X4         A.SANIN      1.5   21.5
2   Sábado     X4         A.SANIN      4.0   12.0
3   Festivo    X4         A.SANIN      0.0   0.0
4   hábil      X5         A.SANIN      66.0  130.0
5   Sábado     X5         A.SANIN      40.0  96.0
6   Festivo    X5         A.SANIN      7.5   43.5'),header=TRUE)

正如你所提到的,Datos重复包含许多相同的“案例”,所以让我们在Datos添加两行以使示例更清晰:

Datos<-rbind(Datos,data.frame(tipo=c('hábil','Sábado'),estacion='A.SANIN',hora='X4',usos=c('23','3')))
#     tipo   estacion hora usos
# 1  hábil    A.SANIN   X4   11 # This one neither below y1 or above y2
# 2  hábil     ALAMOS   X4    4
# 3  hábil   AMANECER   X4   45
# 4  hábil   AMERICAS   X4    2
# 5  hábil   ATANASIO   X4   10
# 6  hábil BELALCAZAR   X4    5
# 7  hábil    A.SANIN   X4   23 # This one is above y2 (21.5), so we want to find it.
# 8 Sábado    A.SANIN   X4    3 # This one is below y1 (4.0), so we want to find it. 

现在运行我之前给你的代码:

# Rename the columns of todo to match Datos
names(todo)<-c('tipo','hora','estacion','y1','y2')
# Merge the two.
Datos.y.todo<-merge(Datos,todo)
# Notice how the y1 and y2 values are now repeated for easy comparison.
#     tipo estacion hora usos  y1   y2
# 1  hábil  A.SANIN   X4   11 1.5 21.5 # We don't want this row.
# 2  hábil  A.SANIN   X4   23 1.5 21.5 # We want this row.
# 3 Sábado  A.SANIN   X4    3 4.0 12.0 # We want this row.

最后,您可以过滤所需的行:

with(Datos.y.todo, Datos.y.todo[usos<y1 | usos>y2, ])

#     tipo estacion hora usos  y1   y2
# 2  hábil  A.SANIN   X4   23 1.5 21.5
# 3 Sábado  A.SANIN   X4    3 4.0 12.0