【问题标题】:Iterate over every value in data frame and compare it with a mean within a column, return a data frame遍历数据框中的每个值并将其与列中的平均值进行比较,返回一个数据框
【发布时间】:2018-06-26 15:59:01
【问题描述】:

我正在努力编写一个函数,该函数将遍历数据框中的每个值,并仅返回一个数据框,其中的值不符合阈值但具有相同的列名。

这是一个数据框:

salary <- c(21000, 23400, 26800)
bonus <- c(350, 400, 170)
startdate <- as.Date(c('2010-11-1','2010-11-2','2010-11-3'))
df <- data.frame(startdate, salary, bonus)

这是我的功能:

def2 <- function(x, column){
  d = NULL
  for (row in 1:nrow(x)) {
  val <- x[row,column]
  dat <- x[row, "startdate"]
  m <- mean(x[,column])
  y <- (as.Date(dat)-2)
    if (val < m) {
      if (val < y) {
        print('Number is too low')
      } else {
        susp_date = paste(dat)
        value = paste(val)
        d = rbind(d, data.frame(susp_date, value))
      }
    } else {
      next
    }
  }
  return (d)
}

所以基本上,我得到了或多或少想要的输出:我可以看到列中小于平均值的值。这是我得到的输出:

susp_date value
1 2010-11-01 21000
2 2010-11-02 23400

但我想将列的名称和顺序保存在输入数据框中,并为所有列提供此视图,而不仅仅是一个列。

我的梦想是我得到一个数据框作为输出,其列与原始列相同,但如果值低于列中的平均值并且小于对应于值的值,则值将替换为 1 (开始日期 - 2 天)如果不满足这些条件,则为 0:

   startdate salary bonus
1 2010-11-01  1       0
2 2010-11-02  1       0
3 2010-11-03  0       1

我尝试了不同的方法,包括复制数据框然后动态填充它;使用 lapply (在我的情况下应该保持几个条件)并将它们混合但没有成功.. 任何帮助将不胜感激!

【问题讨论】:

  • start_date的目的是什么?
  • “我的梦想是我得到一个数据框作为输出,其列与原始列相同,但如果值低于组内的平均值,则将值替换为 1,并且0 如果一个值大于平均值...”那么你可能应该举一个有分组列的例子。
  • @Parfait 我还有一个条件是用同一列中的一个值检查每个值 -2 天。所以基本上我有两个条件:与列中的平均值和对应于追溯日期的值进行比较。
  • @Gregor 与每列中的平均值进行比较,现在将对其进行编辑,谢谢
  • 关于代码的几点说明:1) 不要使用paste(val)paste(dat),它将转换为character 类。尤其是val,您可能希望保留为数字。 2)如果可能的话,遍历列几乎总是比遍历行更好。 3) 尽量不要在循环中使用rbindcbind 事物 - 将输出初始化为正确的大小并“填补空白”比在每次迭代中“增长”一个对象要高效得多。 4)colMeans函数非常有用。

标签: r function datetime data-manipulation


【解决方案1】:

看起来这就是你想要的。如果不是,这个帖子会调整。

library(dplyr)

df%>%
mutate_if(is.numeric, funs(as.numeric(. < mean(.))))

  startdate salary bonus
1 2010-11-01      1     0
2 2010-11-02      1     0
3 2010-11-03      0     1

【讨论】:

  • 值得注意的是,这可以很容易地与group_by 结合来实现OP的“梦想”。
  • 当然可以。如果有组,则需要group_by。不幸的是,OP的问题没有提供有关团体的信息。真的有点模糊。
  • 另外,OP 对追溯日期条件的解释毫无价值。
  • @InfiniteFlashChess 谢谢,总是忘记 dplyr 是多么强大。但是我还有一个条件是追溯日期,这就是为什么要考虑编写一个函数
【解决方案2】:

这是一个不使用任何库的答案。您所要做的就是在您的函数中使用sapplyifelseSapply 遍历列中的每个元素。编辑为包括这两个条件。 :

def2<-function(x){
  m<-mean(x, na.rm=T)
  sapply(x, function(y){
    ifelse(y>m,1,0)
  })
}

# Both conditions (assumes date is ordered (ascending) and doesn't have any duplicates!)
def2<-function(w,x){
  m<-mean(x, na.rm=T)
  sapply(seq_along(x), function(y){
    n<-w[y]-2
    o<-df$salary[df$startdate==n]
    ifelse((x[y]>m & x[y]>o) ,1,0)
  })
}

# Applying the function
df$bonus<-def2(x=df$salary,w=df$startdate)

【讨论】:

    猜你喜欢
    • 2018-06-27
    • 1970-01-01
    • 2018-03-14
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 2020-08-13
    • 1970-01-01
    相关资源
    最近更新 更多