应用子集函数(或基于子集的自定义函数)

时间:2017-10-30 11:15:14

标签: r

我正在尝试找到一种方法来使用apply函数以及subset(或基于subset的自定义函数)。我知道已经提出了类似的问题,我的问题更具体一点。我需要根据多个变量对多个数据集的某些部分进行子集化。我有几个"类型"数据框架结构,其中一个看起来类似于:

colour  shade   value
RED LIGHT   -1.05
RED LIGHT   -1.37
RED LIGHT   -0.32
RED LIGHT   0.87
RED LIGHT   -0.2
RED DARK    0.52
RED DARK    -0.2
RED DARK    0.64
RED DARK    1.12
RED DARK    4
BLUE    LIGHT   0.93
BLUE    LIGHT   0.78
BLUE    LIGHT   -1.84
BLUE    LIGHT   -0.5
BLUE    LIGHT   -1.11
BLUE    DARK    -4.86
BLUE    DARK    1.11
BLUE    DARK    0.14
BLUE    DARK    0.12
BLUE    DARK    -1.65
GREEN   LIGHT     3.13
GREEN   LIGHT   2.65
GREEN   LIGHT   -2.36
GREEN   LIGHT   -3.11
GREEN   LIGHT   3.49
GREEN   DARK    1.91
GREEN   DARK    -1.1
GREEN   DARK    -1.93
GREEN   DARK    1
GREEN   DARK    -0.23

我有很多这些。它们的名称存储在

list.dfs.names=df1,df2,df3

基于此,我需要使用subset或基于它的自定义函数:

customSubset=function(df,col,shade){subset(df,df$colour %in% col & df$shade %in% shade)}

我使用这样的自定义函数,因为我说我有几种类型的df结构,它加快了我的工作。它的工作原理如下:

example=customSubset(df1,"BLUE","DARK")

,输出为:

   colour shade value
11   BLUE LIGHT  0.93
12   BLUE LIGHT  0.78
13   BLUE LIGHT -1.84
14   BLUE LIGHT -0.50
15   BLUE LIGHT -1.11
16   BLUE  DARK -4.86
17   BLUE  DARK  1.11
18   BLUE  DARK  0.14
19   BLUE  DARK  0.12
20   BLUE  DARK -1.65

直到现在我正在使用for循环,但我想将我的方法改为apply,这似乎更方便,特别是在需要嵌套循环的情况下。所以我累了:

lapply(customSubset(list.dfs.names, "BLUE","DARK") )

lapply(list.dfs.names, customSubset("BLUE","DARK") )

没有成功。任何人都可以在这个问题上尽一份力,我不认为我清楚地理解apply循环是如何工作的。但是我对for方法非常熟悉,所以任何有关差异的其他解释都将受到赞赏。

如果customSubset无效,我可以使用常规subset或与上述example产生相同结果的任何其他方法。

提前谢谢

编辑:这里是生成类似df的代码我发布的例子:

`data.frame("colour"=(c(rep("RED",10),rep("BLUE",10),rep("GREEN",10)))
           ,"shade"=c(rep(c(rep("LIGHT",5),rep("DARK",5)),3))
           , runif(30,min=0,max=1))`

EDIT2:根据要求,我正在编辑我的帖子,以便在year问题上展开它。我的dfs来自不同的年份(每个来自多个),例如:df.1.2012df.2.2012df.1.2011等等。主要问题是我永远不需要在所有dfs中引用同一年(这将非常容易),而是我需要根据特定范围对数据进行子集化(例如:year+2year-1) 。我曾经创建了所需年份的列表(例如year+2,它将是list.year=c(2014,2014,2013)),它与我的dfs列表配对(它与for loop如何一起工作)。

我需要为apply方法找到类似的方法。这是一个例子:

set.seed(200)

 df_2014=data.frame(colour=(c(rep("RED",10),rep("BLUE",10),rep("GREEN",10)))
           ,shade=c(rep(c(rep("LIGHT",5),rep("DARK",5)),3))
           ,year=c(rep(2011:2015,6))
           ,value=runif(30,min=0,max=1))

 df_2013=data.frame(colour=(c(rep("RED",10),rep("BLUE",10),rep("GREEN",10)))
           ,shade=c(rep(c(rep("LIGHT",5),rep("DARK",5)),3))
           ,year=c(rep(2011:2015,6))
           ,value=runif(30,min=0,max=1))
horizon=+1

subset(df_2014, df_2014$colour %in% "BLUE" & df_2014$shade %in% "DARK" & df_2014$year %in% c(2014+horizon))
subset(df_2013, df_2013$colour %in% "BLUE" & df_2013$shade %in% "DARK" & df_2013$year %in% c(2013+horizon))

所以我添加了多年的专栏,我称之为year并在年后命名为dfs(所以year+1将在这里2014+1)。地平线是自我解释的。结果是:

#df_2014
      colour shade year   value
 20   BLUE  DARK 2015 0.6463296

#df_2013

   colour shade year     value
20   BLUE  DARK 2015 0.6532767

我需要使用apply函数列出数据框(在此编辑list.df=list(df_2014,df_2013)中,如前例所示,但这次添加子集条件year+horizon(并且可能将所有结果放入一个df,但这不是主要问题。)

总结:当您在subset中查看此部分中的year+horizon函数时,year必须根据其引用的循环中的df(来自列表)进行更改(而horizon是不变的。

如果你无法理解我的意思请告诉我,我试着非常具体。

1 个答案:

答案 0 :(得分:2)

问题似乎是构造

subset(df,df$colour %in% col & df$shade %in% shade)

您正在使用subset,它评估第一个参数df的环境中的逻辑表达式,然后执行df$shade %in% shade。这相当于shade %in% shade,因为df是第一个参数。你应该按如下方式重写函数,使用不同的名字就可以了。

customSubset <- function(DF, COL, SHADE){
    subset(DF, colour %in% COL & shade %in% SHADE)
}

现在一切都按预期工作了。

set.seed(5601)    # make the results reproducible

df1 <- data.frame(colour = sample(c("RED", "GREEN", "BLUE"), 30, TRUE),
                  shade = sample(c("LIGHT", "DARK"), 30, TRUE),
                  value = rnorm(30, sd = 9))
df2 <- data.frame(colour = c(rep("RED",10), rep("BLUE",10), rep("GREEN",10))
           ,shade=c(rep(c(rep("LIGHT",5),rep("DARK",5)), 3))
           , value = runif(30,min=0,max=1))

list.dfs <- list(df1, df2)

customSubset(df1,"BLUE","DARK")
#   colour shade      value
#5    BLUE  DARK   4.288107
#6    BLUE  DARK   2.860724
#8    BLUE  DARK -10.720379
#10   BLUE  DARK -15.407090
#14   BLUE  DARK  -2.259848
#30   BLUE  DARK -18.364494

# apply the function to all df's in the list
# both forms are equivalent
lapply(list.dfs, function(x) customSubset(x, "BLUE", "DARK"))
lapply(list.dfs, customSubset, "BLUE", "DARK")