我正在尝试找到一种方法来使用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.2012
,df.2.2012
,df.1.2011
等等。主要问题是我永远不需要在所有dfs中引用同一年(这将非常容易),而是我需要根据特定范围对数据进行子集化(例如:year+2
或year-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
是不变的。
如果你无法理解我的意思请告诉我,我试着非常具体。
答案 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")