2016-09-17 72 views
-2

我想创建一个函数,允许在运行回归分析之前将数据框的选定列转换为分类数据类型(因子)。R - 从字符串获取数据帧的列

问题是如何使用字符串(字符)从数据框中切出特定列。

例子:

strColumnNames <- "Admit,Rank" 
    strDelimiter <- "," 
    strSplittedColumnNames <- strsplit(strColumnNames, strDelimiter) 
    for(strColName in strSplittedColumnNames[[1]]){ 
    dfData$as.name(strColName) <- factor(dfData$get(strColName)) 
    } 

尝试:

dfData$as.name() 
dfData$get(as.name()) 
dfData$get() 

错误消息: 错误:试图将非功能

任何帮助将不胜感激!谢谢!!!

+0

我不知道打勾并感谢您的指导。看起来tick对用户来说非常重要 - 在这里很可怕。 – AiRiFiEd

回答

1

您需要更改

dfData$as.name(strColName) <- factor(dfData$get(strColName)) 

dfData[[strColName]] <- factor(dfData[[strColName]]) 

您可以为更多的阅读?"[["

就你而言,列名是编程生成的,[[]]是唯一的出路。也许这个例子就足以明确说明的$问题:

dat <- data.frame(x = 1:5, y = 2:6) 
z <- "x" 

dat$z 
# [1] NULL 

dat[[z]] 
# [1] 1 2 3 4 5 

至于其他的答案

apply肯定是不行的,因为你申请的功能是as.factorfactorapply总是在一个矩阵上工作(如果你给它一个数据帧,它会先将它转换成一个矩阵)并返回一个矩阵,而矩阵中不能有因子数据类。考虑这个例子:

x <- data.frame(x1 = letters[1:4], x2 = LETTERS[1:4], x3 = 1:4, stringsAsFactors = FALSE) 
x[, 1:2] <- apply(x[, 1:2], 2, as.factor) 

str(x) 
#'data.frame': 4 obs. of 3 variables: 
# $ x1: chr "a" "b" "c" "d" 
# $ x2: chr "A" "B" "C" "D" 
# $ x3: int 1 2 3 4 

注意,你仍然有字符变量而不是因子。正如我所说的,我们必须使用lapply

x[1:2] <- lapply(x[1:2], as.factor) 

str(x) 
#'data.frame': 4 obs. of 3 variables: 
# $ x1: Factor w/ 4 levels "a","b","c","d": 1 2 3 4 
# $ x2: Factor w/ 4 levels "A","B","C","D": 1 2 3 4 
# $ x3: int 1 2 3 4 

现在我们看到的因子类x1x2

对数据帧使用apply从来就不是一个好主意。如果阅读的apply源代码:

dl <- length(dim(X)) 
    if (is.object(X)) 
    X <- if (dl == 2L) 
     as.matrix(X) 
    else as.array(X) 

你看到的数据帧(其具有2维)将被裹挟第一至矩阵。这非常慢。如果您的数据框列有多个不同的类,则生成的矩阵将只有1个类。谁知道这种强制的结果会是什么。

然而apply写R中没有C,用普通for循环:

for (i in 1L:d2) { 
     tmp <- forceAndCall(1, FUN, newX[, i], ...) 
     if (!is.null(tmp)) 
      ans[[i]] <- tmp 

所以它只不过是一个明确的for循环你写你自己更好。

0

我会用不同的方法。

创建要改变的因素列名的载体:

factorCols <- c("Admit", "Rank") 

通过索引然后提取这些列:

myCols <- which(names(dfData) %in% factorCols) 

最后,使用适用于这些列改为因素:

dfData[,myCols] <- lapply(dfData[,myCols],as.factor) 
+0

嘿greghk,这个方法的选择背后有没有什么原因与哲源提出的?谢谢! – AiRiFiEd

+0

@ZheyuanLi你是对的,lapply对于未来的重现性会更好。我的观点是,通过使用* apply函数而不是for循环,可以使代码更加简洁易懂 – greghk

+0

@ZheyuanLi我已经编辑以反映您对lapply的要求 – greghk