【发布时间】:2017-10-31 22:05:38
【问题描述】:
我正在尝试找到一种方法来使用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 中,但这不是这里的主要问题)。
结论:当您在year+horizon 的这一部分中查看我的subset 函数时,year 必须根据循环中引用的 df(from list) 进行更改(而horizon 是恒定的) .
如果您无法理解我的意思,请告诉我,我试图非常具体。
【问题讨论】:
-
将所有数据框放在一个列表中,使用
lapply(list, function(x) {return(customSubset(x, "BLUE","DARK"))}) -
它返回给我错误:
Error: $ operator is invalid for atomic vectors。我做错了什么? -
假设 df1 是发布在 OP 中的 data.frame,而 df2 是类似的 data.frame :
lapply(list(df1, df2), function(x) {return(customSubset(x, "BLUE","DARK"))})应该可以工作。 -
dplyr::filter和purrr::map也可以试试!
标签: r