Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/72.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系数扩展为每个系数级别的1/0指标变量集合_R - Fatal编程技术网

自动将R系数扩展为每个系数级别的1/0指标变量集合

自动将R系数扩展为每个系数级别的1/0指标变量集合,r,R,我有一个R数据框,其中包含一个我想要“扩展”的因子,因此对于每个因子级别,在一个新的数据框中有一个关联的列,其中包含一个1/0指标。例如,假设我有: df.original <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c(1,2,3,4)) df.original可能虚拟变量与您想要的类似。 然后,model.matrix很有用: > with(df.original, data.frame(model.matr

我有一个R数据框,其中包含一个我想要“扩展”的因子,因此对于每个因子级别,在一个新的数据框中有一个关联的列,其中包含一个1/0指标。例如,假设我有:

df.original <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c(1,2,3,4))

df.original可能虚拟变量与您想要的类似。
然后,model.matrix很有用:

> with(df.original, data.frame(model.matrix(~eggs+0), ham))
  eggsbar eggsfoo ham
1       0       1   1
2       0       1   2
3       1       0   3
4       1       0   4

使用
model.matrix
功能:

model.matrix( ~ Species - 1, data=iris )

如果您的数据框仅由因子组成(或者您正在处理所有因子的变量子集),您还可以使用
ade4
软件包中的
acm.disjoncif
功能:

R> library(ade4)
R> df <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c("red","blue","green","red"))
R> acm.disjonctif(df)
  eggs.bar eggs.foo ham.blue ham.green ham.red
1        0        1        0         0       1
2        0        1        1         0       0
3        1        0        0         1       0
4        1        0        0         0       1
R>库(ade4)
R> df acm.disjonctif(df)
鸡蛋。条状鸡蛋。富火腿。蓝色火腿。绿色火腿。红色
1        0        1        0         0       1
2        0        1        1         0       0
3        1        0        0         1       0
4        1        0        0         0       1

不完全是您所描述的情况,但它也很有用…

使用
重塑2
包的快速方法:

require(reshape2)

> dcast(df.original, ham ~ eggs, length)

Using ham as value column: use value_var to override.
  ham bar foo
1   1   0   1
2   2   0   1
3   3   1   0
4   4   1   0

请注意,这将精确地生成所需的列名

刚刚遇到这个旧线程,我想我应该添加一个函数,利用ade4获取由因子和/或数字数据组成的数据帧,并返回一个以因子作为伪代码的数据帧

dummy <- function(df) {  

    NUM <- function(dataframe)dataframe[,sapply(dataframe,is.numeric)]
    FAC <- function(dataframe)dataframe[,sapply(dataframe,is.factor)]

    require(ade4)
    if (is.null(ncol(NUM(df)))) {
        DF <- data.frame(NUM(df), acm.disjonctif(FAC(df)))
        names(DF)[1] <- colnames(df)[which(sapply(df, is.numeric))]
    } else {
        DF <- data.frame(NUM(df), acm.disjonctif(FAC(df)))
    }
    return(DF)
} 

虚拟来自
nnet
软件包的延迟输入
class.ind

library(nnet)
 with(df.original, data.frame(class.ind(eggs), ham))
  bar foo ham
1   0   1   1
2   0   1   2
3   1   0   3
4   1   0   4

我需要一个函数来“分解”更灵活的因子,并基于ade4包中的acm.disjonctif函数制作了一个函数。 这允许您选择分解值,即acm.disjonctif中的0和1。它只会分解“很少”级别的因素。保留数字列

# Function to explode factors that are considered to be categorical,
# i.e., they do not have too many levels.
# - data: The data.frame in which categorical variables will be exploded.
# - values: The exploded values for the value being unequal and equal to a level.
# - max_factor_level_fraction: Maximum number of levels as a fraction of column length. Set to 1 to explode all factors.
# Inspired by the acm.disjonctif function in the ade4 package.
explode_factors <- function(data, values = c(-0.8, 0.8), max_factor_level_fraction = 0.2) {
  exploders <- colnames(data)[sapply(data, function(col){
      is.factor(col) && nlevels(col) <= max_factor_level_fraction * length(col)
    })]
  if (length(exploders) > 0) {
    exploded <- lapply(exploders, function(exp){
        col <- data[, exp]
        n <- length(col)
        dummies <- matrix(values[1], n, length(levels(col)))
        dummies[(1:n) + n * (unclass(col) - 1)] <- values[2]
        colnames(dummies) <- paste(exp, levels(col), sep = '_')
        dummies
      })
    # Only keep numeric data.
    data <- data[sapply(data, is.numeric)]
    # Add exploded values.
    data <- cbind(data, exploded)
  }
  return(data)
}
#用于分解被认为是分类的因素的函数,
#也就是说,它们没有太多的级别。
#-data:分类变量将在其中分解的data.frame。
#-值:不相等或等于某个级别的值的分解值。
#-max_factor_level_fraction:作为列长度分数的最大级别数。设置为1可分解所有因子。
#灵感来源于ade4软件包中的acm.disjonctif函数。

分解因子这里有一个更明确的方法。我使用model.matrix创建虚拟布尔变量,然后将其合并回原始数据帧

df.original <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c(1,2,3,4))
df.original
#   eggs ham
# 1  foo   1
# 2  foo   2
# 3  bar   3
# 4  bar   4

# Create the dummy boolean variables using the model.matrix() function.
> mm <- model.matrix(~eggs-1, df.original)
> mm
#   eggsbar eggsfoo
# 1       0       1
# 2       0       1
# 3       1       0
# 4       1       0
# attr(,"assign")
# [1] 1 1
# attr(,"contrasts")
# attr(,"contrasts")$eggs
# [1] "contr.treatment"

# Remove the "eggs" prefix from the column names as the OP desired.
colnames(mm) <- gsub("eggs","",colnames(mm))
mm
#   bar foo
# 1   0   1
# 2   0   1
# 3   1   0
# 4   1   0
# attr(,"assign")
# [1] 1 1
# attr(,"contrasts")
# attr(,"contrasts")$eggs
# [1] "contr.treatment"

# Combine the matrix back with the original dataframe.
result <- cbind(df.original, mm)
result
#   eggs ham bar foo
# 1  foo   1   0   1
# 2  foo   2   0   1
# 3  bar   3   1   0
# 4  bar   4   1   0

# At this point, you can select out the columns that you want.
df.原始毫米
#eggsbar eggsfoo
# 1       0       1
# 2       0       1
# 3       1       0
# 4       1       0
#属性(,“分配”)
# [1] 1 1
#属性(,“对比度”)
#属性(,“对比度”)$鸡蛋
#[1]“对照治疗”
#根据需要从列名中删除“eggs”前缀。

colnames(mm)很好。但是要小心火腿的复制品。比如说,d@Kohske,是的,但我假设
ham
是唯一的行id。如果
ham
不是唯一的id,则必须使用其他唯一id(或创建一个虚拟id),并使用该id代替
ham
。将分类标签转换为二进制指示符只对唯一ID有意义。我可以补充一点,对我来说,这种方法比使用
cast
快得多。@GregSnow我回顾了
“公式”和
“模型.矩阵”
“的第2段,但不清楚(可能是因为我缺乏矩阵代数和模型公式方面的深度知识)。在深入挖掘之后,我发现-1只是指定不包含“截距”列。如果您省略-1,您将在输出中看到一个截取列1,其中一个二进制列被省略。您可以根据其他列的值为0的行来查看省略的列是1的哪些值。文档似乎很神秘-还有其他好的资源吗?@Ryancase,有很多在线教程还有关于R/S的书(有几本在R-project.org网页上有简要说明)。我自己对S和R的学习是相当折衷的(而且很长),因此,我不是最适合就当前书籍/教程如何吸引初学者发表意见的人。然而,我是一个实验迷。在新的R课程中尝试一些东西可能非常有启发性,也不会有危险(发生在我身上的最坏情况是R崩溃,而这很少导致R的改进).Stackoverflow是了解发生了什么的一个很好的资源。如果您想转换所有因子列,可以使用:
model.matrix(~,data=iris)[,-1]
@colin,不是全自动的,但是你可以使用
naresid
在使用
na.exclude
后将缺少的值放回。一个简单的例子:
tmp谢谢,这对我帮助很大,因为它使用的内存比model.matrix少!我喜欢变量的命名方式;我不喜欢当ey(IMHO)应该是逻辑的。
# Function to explode factors that are considered to be categorical,
# i.e., they do not have too many levels.
# - data: The data.frame in which categorical variables will be exploded.
# - values: The exploded values for the value being unequal and equal to a level.
# - max_factor_level_fraction: Maximum number of levels as a fraction of column length. Set to 1 to explode all factors.
# Inspired by the acm.disjonctif function in the ade4 package.
explode_factors <- function(data, values = c(-0.8, 0.8), max_factor_level_fraction = 0.2) {
  exploders <- colnames(data)[sapply(data, function(col){
      is.factor(col) && nlevels(col) <= max_factor_level_fraction * length(col)
    })]
  if (length(exploders) > 0) {
    exploded <- lapply(exploders, function(exp){
        col <- data[, exp]
        n <- length(col)
        dummies <- matrix(values[1], n, length(levels(col)))
        dummies[(1:n) + n * (unclass(col) - 1)] <- values[2]
        colnames(dummies) <- paste(exp, levels(col), sep = '_')
        dummies
      })
    # Only keep numeric data.
    data <- data[sapply(data, is.numeric)]
    # Add exploded values.
    data <- cbind(data, exploded)
  }
  return(data)
}
df.original <-data.frame(eggs = c("foo", "foo", "bar", "bar"), ham = c(1,2,3,4))
df.original
#   eggs ham
# 1  foo   1
# 2  foo   2
# 3  bar   3
# 4  bar   4

# Create the dummy boolean variables using the model.matrix() function.
> mm <- model.matrix(~eggs-1, df.original)
> mm
#   eggsbar eggsfoo
# 1       0       1
# 2       0       1
# 3       1       0
# 4       1       0
# attr(,"assign")
# [1] 1 1
# attr(,"contrasts")
# attr(,"contrasts")$eggs
# [1] "contr.treatment"

# Remove the "eggs" prefix from the column names as the OP desired.
colnames(mm) <- gsub("eggs","",colnames(mm))
mm
#   bar foo
# 1   0   1
# 2   0   1
# 3   1   0
# 4   1   0
# attr(,"assign")
# [1] 1 1
# attr(,"contrasts")
# attr(,"contrasts")$eggs
# [1] "contr.treatment"

# Combine the matrix back with the original dataframe.
result <- cbind(df.original, mm)
result
#   eggs ham bar foo
# 1  foo   1   0   1
# 2  foo   2   0   1
# 3  bar   3   1   0
# 4  bar   4   1   0

# At this point, you can select out the columns that you want.