R 使用索引将数据框列转换为因子

R 使用索引将数据框列转换为因子,r,dataframe,indexing,types,R,Dataframe,Indexing,Types,我把一些结果放在一个数据框中。我有一些因子列和许多数值列。根据问题的答案,我可以通过索引轻松地将数字列转换为数字列 #create example data df = data.frame(replicate(1000,sample(1:10,1000,rep=TRUE))) df$X1 = LETTERS[df$X1] df$X2 = LETTERS[df$X2] df$X3 = LETTERS[df$X3] df[-1] <- sapply(df[-1], function(x) if

我把一些结果放在一个数据框中。我有一些因子列和许多数值列。根据问题的答案,我可以通过索引轻松地将数字列转换为数字列

#create example data
df = data.frame(replicate(1000,sample(1:10,1000,rep=TRUE)))
df$X1 = LETTERS[df$X1]
df$X2 = LETTERS[df$X2]
df$X3 = LETTERS[df$X3]
df[-1] <- sapply(df[-1], function(x) ifelse(runif(length(x)) < 0.1, NA, x))

#find columns that are factors
factornames = c("X1", "X2", "X3")
factorfilt = names(df) %in% factornames

#convert non-factor columns to numeric
df[, !factorfilt] = as.numeric(as.character(unlist(df[, !factorfilt])))
如果调用
类(df$X1)
,所有这些都返回
“character”
,而如果运行
df$X1=as.factor(df$X1)
则返回
“factor”


为什么当我将
称为.factor
时,这种索引方式不起作用,而当我将
称为.numeric
时,这种方法会起作用?

您应该观察您正在做的事情的一些行为方面。按原样定义数据:

df = data.frame(replicate(1000,sample(1:10,1000,rep=TRUE)))
df$X1 = LETTERS[df$X1]
df$X2 = LETTERS[df$X2]
df$X3 = LETTERS[df$X3]
df[-1] <- sapply(df[-1], function(x) ifelse(runif(length(x)) < 0.1, NA, x))

factornames = c("X1", "X2", "X3")
factorfilt = names(df) %in% factornames
df[, !factorfilt] = as.numeric(as.character(unlist(df[, !factorfilt])))
这里需要注意的重要一点是,
test
不是数据帧。它是一个向量,您试图保存一个数据帧的三列。我认为我们应该质疑将数据帧转换为向量以存储在数据帧中是否明智

然后考虑你的第二个任务:

test2 <- as.factor(as.character(unlist(df[, factorfilt])))
class(test2) # factor
length(test2) # 3000
此时,
X4
X1000
都是
integer
类列。当你跑的时候

df[-1] <- sapply(df[-1], function(x) ifelse(runif(length(x)) < 0.1, NA, x))
原始类被保留,不需要将它们转换回数值类。类似地,我们可以通过
X3
X1
转换为具有

df[, factorfilt] <- lapply(df[, factorfilt], as.factor)

df[,factorfilt]你应该观察你正在做的事情的一些行为方面。按原样定义数据:

df = data.frame(replicate(1000,sample(1:10,1000,rep=TRUE)))
df$X1 = LETTERS[df$X1]
df$X2 = LETTERS[df$X2]
df$X3 = LETTERS[df$X3]
df[-1] <- sapply(df[-1], function(x) ifelse(runif(length(x)) < 0.1, NA, x))

factornames = c("X1", "X2", "X3")
factorfilt = names(df) %in% factornames
df[, !factorfilt] = as.numeric(as.character(unlist(df[, !factorfilt])))
这里需要注意的重要一点是,
test
不是数据帧。它是一个向量,您试图保存一个数据帧的三列。我认为我们应该质疑将数据帧转换为向量以存储在数据帧中是否明智

然后考虑你的第二个任务:

test2 <- as.factor(as.character(unlist(df[, factorfilt])))
class(test2) # factor
length(test2) # 3000
此时,
X4
X1000
都是
integer
类列。当你跑的时候

df[-1] <- sapply(df[-1], function(x) ifelse(runif(length(x)) < 0.1, NA, x))
原始类被保留,不需要将它们转换回数值类。类似地,我们可以通过
X3
X1
转换为具有

df[, factorfilt] <- lapply(df[, factorfilt], as.factor)

df[,factorfilt]因子
as.factor
as.character
等作用于向量
而非数据帧
。您需要循环遍历列,然后按照akrun的注释执行
factor
,使用
lappy
遍历所选列并执行强制:
df[,factorfilt]
numeric
是一种原子数据类型,而factor是一种特殊的数据类型,它将标签映射到整数,并有自己的类。
data.frame
有自己的类,尝试将
中的值重新分配为.factor(unlist(df[,factorfilt])
(这是一个factor)到data.frame的多列中,会导致函数在重新分配之前将未列出的向量转换为字符。所涉及的函数相当复杂,键入
`[通常,
mutate\u if
是将一种类型的所有列转换为另一种类型的一种很好的方法。关于尝试使用因子矩阵的一个非常详细的回答:。从这个答案来看,当您使用
矩阵(…)
时,它使用
作为.vector()
在构建矩阵之前对数据进行处理。这是将因子转换为字符的方法(尝试
类(如.vector(因子(c(1,2,3)))
as.factor
as.character
等作用于
向量,而不是
数据.frame
。您需要在列中循环,然后在akrun的注释后执行
factor
操作,使用
lappy
运行所选列并执行强制:
df[,factorfilt]
numeric
是一种原子数据类型,而factor是一种特殊的数据类型,它将标签映射到整数并有自己的类。
data.frame
有自己的类,试图将
中的值重新指定为.factor(unlist(df[,factorfilt])
(这是一个factor)在data.frame的多列中,使函数在重新分配之前将未列出的向量转换为字符。涉及的函数非常复杂,键入
`[通常,
mutate\u if
是将一种类型的所有列转换为另一种类型的好方法。关于尝试使用因子矩阵的一个非常详细的回答:。根据这个答案,当您使用
matrix(…)
时,它在构建矩阵之前对数据使用
as.vector()
。这就是将因子转换为字符的原因(试试
类(如.vector(factor(c(1,2,3)))
)嗯,我根本没有意识到这些事情,谢谢。读到
sapply
lappy
似乎它们是一样的?它们返回的是不同的。
sapply
返回向量或矩阵(在这种特殊情况下,我认为这是一个很长的向量).
lappy
返回一个列表,它将使数据帧的列保持正确的分区。嗯,我根本不知道这些事情,谢谢。阅读关于
sapply
lappy
的文章,它们似乎是一样的?它们返回的内容不同。
sapply
返回向量或矩阵(在这种特殊情况下,我认为这是一个非常长的向量)。
lappy
返回一个列表,它将保持数据帧的列正确分区。