Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 将特定函数应用于数据帧的所有行时出错_R_Dataframe_Plyr - Fatal编程技术网

R 将特定函数应用于数据帧的所有行时出错

R 将特定函数应用于数据帧的所有行时出错,r,dataframe,plyr,R,Dataframe,Plyr,如果这个问题以前已经解决过,我会提前道歉,但是我已经试着把所有与ddply、sapply和apply相关的问题都找遍了,我一辈子都想不出这个问题 我已经编写了一个函数countMonths,它以计费周期中的天、月和总天数作为参数,并返回计费周期所属的日历月数: countMonths <- function(day, month, cycle.days) { month.days <- c(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 3

如果这个问题以前已经解决过,我会提前道歉,但是我已经试着把所有与ddply、sapply和apply相关的问题都找遍了,我一辈子都想不出这个问题

我已经编写了一个函数countMonths,它以计费周期中的天、月和总天数作为参数,并返回计费周期所属的日历月数:

countMonths <- function(day, month, cycle.days) {
  month.days <- c(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
  if (month < 1 | month > 12 | floor(month) != month) {
    cat("Invalid month value, must be an integer from 1 to 12")
  } else if (day < 1 | day > month.days[month]) {
    cat("Invalid day value, must be between 1 and month.days[month]")
  } else if (cycle.days < 0) {
    cat("Invalid cycle.days value, must be >= 0")
  } else {
    nmonths <- 1
    day.ct <- cycle.days - day
    while (day.ct > 0) {
      nmonths <- nmonths + 1
      month <- ifelse(month == 1, 12, month - 1) # sets to previous month    
      day.ct  <- day.ct - month.days[month] # subtracts days of previous month
    }
    nmonths
  }
}
我尝试了几种选择,但没有一种效果好。具体来说,我需要能够将给定变量的值作为标量(或长度为1的向量)传递给数据帧中的每一行,但它们总是作为向量传递:

> cons2$tot.months <- countMonths(cons2$day, cons2$month, cons2$cycle.days)  
Warning messages:
1: In if (month < 1 | month > 12 | floor(month) != month) { :
  the condition has length > 1 and only the first element will be used
2: In if (day < 1 | day > month.days[month]) { :
  the condition has length > 1 and only the first element will be used
3: In if (cycle.days < 0) { :
  the condition has length > 1 and only the first element will be used
4: In while (day.ct > 0) { :
  the condition has length > 1 and only the first element will be used
5: In while (day.ct > 0) { :
  the condition has length > 1 and only the first element will be used
>总消费2美元12个月|楼层(月)!=月份{:
条件的长度大于1,并且只使用第一个元素
2:如果(天<1 |天>月。天[月]{:
条件的长度大于1,并且只使用第一个元素
3:在if(cycle.days<0)中{:
条件的长度大于1,并且只使用第一个元素
4:while(day.ct>0){:
条件的长度大于1,并且只使用第一个元素
5:while(day.ct>0){:
条件的长度大于1,并且只使用第一个元素
我最终能够使用ddply获得正确的结果,将每一行视为自己的组,但这需要很长时间:

cons2 <- ddply(cons2, .(account, year, month, day), transform,
               tot.months = countMonths(day, month, cycle.days)
)

cons2要使函数工作,可以使用
mapply
将函数依次应用于传递给它的所有向量的每个元素。因此,您可以执行以下操作:

mapply(countMonths,cons2$day,cons2$month,cons2$cycle.days)
正如我在评论中提到的那样,有更简单的方法可以做到这一点。例如,我认为这会奏效:

cons2$read.date=as.Date(cons2$read.date)
monnb <- function(d){ lt <- as.POSIXlt(as.Date(d, origin="1900-01-01"));  lt$year*12 + lt$mon }
mondf <- function(d1, d2)  monnb(d2) - monnb(d1) 
mondf(cons2$read.date-cons2$cycle.days,cons2$read.date) + 1


至于对函数的注释,我认为它是有效的,但它没有利用R中的向量运算。我从另一个答案中得到的函数非常灵活,因为它允许您一次向它提供一个完整的日期向量,而不是依次循环每个向量。

如果您使用
dput,将非常方便(负责人(委员会2[-1],10))
,所以我们可以直接剪切并粘贴到会话中。@nograps:done。谢谢你的建议。另外,它没有回答你的具体问题,但它解决了计算日期之间日历月数的问题。我不确定将其标记为重复是否有帮助?我的问题不在于该函数本身-它似乎在工作或者单个输入值。但是,我在将其应用于数据的每一行时遇到了问题。我包含了该函数,因此可以清楚地知道函数返回的内容,以防这影响到我的应用问题。当然,可以使用xts包中的
nmonths
之类的东西来获得更简单的解决方案……这很有效,谢谢!感谢我的支持通过自己的学习,你能描述一下你所看到的功能问题吗?
cons2$read.date=as.Date(cons2$read.date)
monnb <- function(d){ lt <- as.POSIXlt(as.Date(d, origin="1900-01-01"));  lt$year*12 + lt$mon }
mondf <- function(d1, d2)  monnb(d2) - monnb(d1) 
mondf(cons2$read.date-cons2$cycle.days,cons2$read.date) + 1
countMonths <- function(day, month, cycle.days) {
  month.days <- c(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
  stopifnot(month >=1 & month <= 12 & floor(month)==month & cycle.days >=0 & day >= 1 & day <= month.days[month]) 
  nmonths <- 1
  day.ct <- cycle.days - day
  while (day.ct > 0) {
    nmonths <- nmonths + 1
    month <- ifelse(month == 1, 12, month - 1) # sets to previous month    
    day.ct  <- day.ct - month.days[month] # subtracts days of previous month
  }
  nmonths
}