【问题标题】:Combine factor variable levels with less observations together. for all factor variables in a data frame将具有较少观察值的因子变量水平组合在一起。对于数据框中的所有因子变量
【发布时间】:2019-09-17 11:42:22
【问题描述】:

我正在尝试编写一个函数,该函数将查看数据框中的所有因子变量并将所有级别组合在一起,但前提是某个级别包含的观察值少于某个百分比/阈值。

到目前为止,我有一个适用于单个变量的函数,但我正在尝试将该函数应用于数据框中的所有因素。当我尝试将其应用于所有因子变量时,出现错误

# Code to create data frame (df)
var <- factor(c(a <- rep("a", 100), b <- rep("b", 1000), c <- rep("c", 1000), d <- rep("d", 1000), e <- rep("e", 400), f <- rep("f", 100)))
var1 <- factor(c(a1 <- rep("a", 100), b1 <- rep("b", 400), c1 <- rep("c", 1000), d1 <- rep("d", 1000), e1 <- rep("e", 1000), f <- rep("f", 100)))
x_df <- data.frame(var = var, var1 = var1)
str(x_df)


# check the count of each level 
sapply(x_df, function(x){
  table(x)
})

# create the function 
Merge.factors <- function(x, p) { 
  #Combines factor levels in x that are less than a specified proportion, p.
  t <- table(x)                 
  less <- subset(t, prop.table(t) < p)
  more <- subset(t, prop.table(t) >= p)
  other <- rep("Other", sum(less))
  new.table <- c(more, table(other))
  new.x <- as.factor(rep(names(new.table), new.table))
  return(new.x)
}

# applying the function to a single factor variable -  It works!
# This is the expected result 
Merge.factors(x_df$var, 0.15) 

现在我尝试了两种方法将此函数应用于所有因子变量

# First method: 
sapply(x_df, Merge.factors(0.15))   # Give an error, argument P is missing

# 2nd Method:
for (i in 1:ncol(x_df)) {
  x_df[,i] <- Merge.factors(i, 0.15)
}

任何帮助将不胜感激

【问题讨论】:

  • 那么,这个问题与 Rstudio 有什么关系(因此是标签)?因此,如果您在另一个 IDE 中运行它,它可以工作吗?请不要使用RStudio 标签,除非您对 RStudio IDE 有特定问题

标签: r data-manipulation


【解决方案1】:

在您当前的函数中,您需要将阈值作为不同的参数传递

x_df[] <- lapply(x_df, Merge.factors, 0.15)
#Or to be more specific
#x_df[] <- lapply(x_df, function(x) Merge.factors(x, 0.15))

现在检查

lapply(x_df, table)

#$var
#    b     c     d Other 
# 1000  1000  1000   600 

#$var1
#    c     d     e Other 
# 1000  1000  1000   600 

为了排除某些因素,我们可以将函数更改为

Merge.factors <- function(x, p) { 
  t <- table(x)                 
  less <- subset(t, prop.table(t) < p & names(t) != 'e')
  more <- subset(t, prop.table(t) >= p | names(t) == "e")
  other <- rep("Other", sum(less))
  new.table <- c(more, table(other))
  new.x <- as.factor(rep(names(new.table), new.table))
  return(new.x)
}

x_df[] <- lapply(x_df, Merge.factors, 0.15)
lapply(x_df, table)

#$var
#    b     c     d     e Other 
# 1000  1000  1000   400   200 

#$var1
#    c     d     e Other 
# 1000  1000  1000   600 

【讨论】:

  • 谢谢沙吉!也为了更具体的评论,让它更清楚:)
  • 抱歉只添加一件事,如何添加异常?如果'e'是一个类别,那么不要将其组合起来,而是为所有其他人做。谢谢
  • 非常感谢 :) @RonakShah
【解决方案2】:

我稍微更改了函数并硬编码了阈值。下面是新函数,后面是函数对所有列的应用:

# create the function 
Merge_factors <- function(x) { 
  t <- table(x)                 
  less <- subset(t, prop.table(t) < 0.15)
  more <- subset(t, prop.table(t) >= 0.15)
  other <- rep("Other", sum(less))
  new.table <- c(more, table(other))
  new.x <- as.factor(rep(names(new.table), new.table))
  return(new.x)
}

xs_df <- as.data.frame(sapply(x_df, Merge_factors))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 1970-01-01
    • 2013-10-08
    相关资源
    最近更新 更多