【问题标题】:How to create a function that will split continuous variables only to groups equal size groups如何创建一个仅将连续变量拆分为大小相等的组的函数
【发布时间】:2015-08-06 11:50:21
【问题描述】:

我想在我的数据框上运行一个函数,该函数将只找到连续变量,并根据将连续变量划分为 2 个相等大小的组来添加新的分类变量。我有一个代码,用于将变量拆分为组并将其添加为新的分类变量,但是当我尝试在函数中使用它时它不起作用。可能是什么问题?另外,如何避免运行非连续变量? 这是一个玩具数据框:

df <- read.table(text = "         birds    wolfs     
                                    9         7    
                                    8         4    
                                    2         8    
                                    2         3    
                                    8         3    
                                    1         2    
                                    7         1    
                                    1         5    
                                    9         7    
                                    8         7     ",header = TRUE)

我的功能是:

for (i in names(df)) function (x) { as.factor( as.numeric( cut(df$i,2)))  }

【问题讨论】:

  • 或许df[paste0(names(df), 'new')] &lt;- lapply(df, function(x) factor(cut(x, 2, labels=FALSE)))
  • 在您的函数中,您使用的是df$i。我会使用df[,i]。其次,输出需要存储在另一个对象左右。它没有定义。
  • 例如lst &lt;- vector('list', ncol(df)); for(i in seq_along(df)) {lst[[i]] &lt;- as.factor(as.numeric(cut(df[,i], 2)))}
  • 非常感谢@akrun..感谢您的帮助。
  • 您应该能够跳过像这样的非数字变量:df[paste0(names(df), 'new')] &lt;- lapply(df[,sapply(names(df), function(x) is.numeric(df[,x]))], function(x) factor(cut(x, 2, labels=FALSE)))

标签: r dataframe


【解决方案1】:

以下是您的函数中可能存在的一些问题

for (i in names(df)) function (x) { as.factor( as.numeric( cut(df$i,2)))  }
  1. 我会使用 df[,i] 来对列进行子集化,而不是使用 df$i,因为它没有被正确评估
  2. 不需要匿名函数调用function(x)
  3. 输出未存储在另一个变量中。

前两个很容易解决。我们创建一个空的list 对象,其中length 等于'df' (ncol(df)) 的列数。这可用于存储结果('lst')

lst <- vector('list', ncol(df))

现在,我们遍历 'df' 的列(假设所有列都是数字)并将 cut 函数应用于每一列 (cut(df[,i],..)。

for(i in seq_along(df)) {
        lst[[i]] <- as.factor(as.numeric(cut(df[,i], 2)))
 }

我们可以用 'lst' 的输出分配新列

df[paste0(names(df), 'new')] <- lst

替代for 循环的另一个选项是lapplylapply 的结果可以直接分配给新列。

df[paste0(names(df), 'new')] <- lapply(df, function(x)
                   factor(cut(x, 2, labels=FALSE)))

基于 OP 的 cmets 关于单独过滤 numeric 列(甚至不包括二进制列)以应用 cut。我们用vapply 创建一个逻辑索引。它遍历 'df2' 的列并检查它是否是 'numeric' (is.numeric(x)) 以及它是否包含 0、1 (!all(x %in% 0:1)) 以外的值。

 indx <- vapply(df2, function(x) !all(x %in% 0:1) & is.numeric(x), logical(1L))

使用与上面相同的代码,包括“indx”向量

   lst <- vector('list', ncol(df2[indx]))
   for(i in seq_along(df2[indx])) {
       lst[[i]] <- as.factor(as.numeric(cut(df2[indx][,i], 2)))
    }
  df2[paste0(names(df2)[indx], 'new')] <- lst

lapply

 df2[paste0(names(df2)[indx], 'new')] <- lapply(df2[indx],
                  function(x) factor(cut(x, 2, labels=FALSE)))

数据

set.seed(24)
df1 <- data.frame(col1=sample(0:1, 10, replace=TRUE),
           col2=rnorm(10), col3=letters[1:10])
#df - OP's dataset

df2 <- cbind(df1, df)

【讨论】:

    猜你喜欢
    • 2011-08-31
    • 2020-09-13
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    相关资源
    最近更新 更多