R中的条件标签没有循环

时间:2015-02-14 02:55:09

标签: r

我正在尝试找到最好的(性能最好的)让表格的数据框在一年中的四个季节中获得一个名为“季节”的新栏目: MON DAY YEAR 1 1 1 2010 2 1 1 2010 3 1 1 2010 4 1 1 2010 5 1 1 2010 6 1 1 2010

直接这样做是创建一个以MON和DAY列为条件的循环并逐个赋值,但我认为有更好的方法可以做到这一点。我在其他帖子中看到了ifelse:=apply的建议,但所述的大多数问题只是二进制或者可以根据给定的单个函数f来分配值参数。

在我的情况下,我相信包含四个电台标签的矢量和某种条件就足够了,但我不知道如何把所有东西放在一起。我的情况类似于一个开关案例。

2 个答案:

答案 0 :(得分:1)

如果行数很大,使用模运算以及算术运算符将逻辑值强制为0/1的事实会更有效:

d$SEASON <- with(d,  c( "Winter","Spring", "Summer", "Autumn")[
                               1+(( (DAY>=21) + MON-1) %/% 3)%%4 ] )

第一个添加&#34; 1&#34;将括号内的所有结果的%% 4操作范围从0:3移到1:4。第二个减去&#34; 1&#34;将(内部)1:12范围移回0:11,(DAY >= 21)将边界月份向前推进一个。

答案 1 :(得分:0)

我首先给出一个简单的答案,然后我将深入研究细节。 我快速做到这一点的方法是检查MON和DAY的值并输出正确的季节。这是微不足道的:

f=function(m,d){
  if(m==12 && d>=21) i=3
  else if(m>9 || (m==9 && d>=21)) i=2
  else if(m>6 || (m==6 && d>=21)) i=1
  else if(m>3 || (m==3 && d>=21)) i=0
  else i=3
}

这个f函数,给定一天和一个月,将返回一个对应于季节的整数(如果它是整数或字符串则不重要;整数只允许节省一点内存,但它具有技术性。 现在,您要将其应用于data.frame。不需要为此使用循环;我们将使用mapplyd将是我们的模拟data.frame。我们将输出的因子设置得很好。

d=data.frame(MON=rep(1:12,each=30),DAY=rep(1:30,12),YEAR=2012))
d$SEA=factor(
  mapply(f,d$MON,d$DAY),
  levels=0:3,
  labels=c("Spring","Summer","Autumn","Winter")
)

你有它!

我意识到季节永远不会改变21岁。如果需要微调,则应将三维数组定义为全局变量,以存储准确的天数。给定一个季节和一年,您可以访问相应的日期并使用正确的调用替换f函数中的&#34; 21&#34;您显然会为该年添加第三个参数。

关于你在问题中提到的事情:

  • ifelse是&#34; functionnal&#34;做一个条件测试的方法。在原子变量上,它只比条件语句略好,但它是矢量化的,这意味着如果参数是一个向量,它将在其元素上循环自身。我不熟悉它,但它是获得优化解决方案的方法
  • mapply源自&#34; sapply家庭的apply&#34;并允许在向量上调用具有多个参数的函数(请参阅?mapply
  • 我不认为:=是R中的标准运算符,这让我想到了下一点:
  • data.table!它是一个包,它提供了一个新的结构,可以扩展data.frame以进行快速计算和输入(除其他外)。 :=是该包中的运算符,允许定义新列。在我们的例子中,如果d[,SEA:=mapply(f,MON,DAY)]是data.table,则可以写d

如果您真的关心性能,我不能坚持使用data.table,因为如果您有大量数据,这是一项重大改进。我不知道它是否会真正影响我使用我提出的解决方案计算时间。