【问题标题】:Working with Dataframes within R, what is level and factor在 R 中使用数据框,什么是水平和因子
【发布时间】:2019-08-07 12:28:09
【问题描述】:

有人可以帮我解决数据框中的因素和水平吗?我很困惑这是如何工作的。

这是我想要做的 --> 如何将两行添加到具有正确数据类型的 df.empty 中:

df.empty <- data.frame(column1 = numeric(), column2 = character(), column3 = factor())
df.empty$column3<-factor(df.empty$column3,levels=c("A","B","C"))

我尝试了两件事:

newRow <- c(-2,"MyString","B")
incorrectRow <- c(-2,"MyString","C")

第一个有效,第二个无效,我不知道为什么。它们是相同的格式,我尝试将"C" 更改为"B""A",仍然不起作用。

我认为这与上面的=c("A","B",C") 代码级别有关,但不确定如何。

【问题讨论】:

  • 您可以在其中添加数据并在之后设置列类 - 如果这就是您的意思。在实际获取这些值之前,您是否需要设置因子水平?
  • 解释基本概念的有用帖子:datamentor.io/r-programming/factor

标签: r dataframe


【解决方案1】:

如果您来自统计背景,您可以将因子视为分类变量。 在 R 中,因子是一个分类变量,可以包含多个级别。级别是此变量的不同值的数量。

让我们加载一个数据框来检查它。

data("PlantGrowth")
head(PlantGrowth)
#you can see here output of categorical column called 'group'
#
str(PlantGrowth)
#by typing fuction str(), it will till you that this column is a factor which has 3 levels ("ctrl", "trt1" , "trt2")
#

输出

头部(植物生长)

  weight group
1   4.17  ctrl
2   5.58  ctrl
3   5.18  ctrl
4   6.11  ctrl
5   4.50  ctrl
6   4.61  ctrl

str(植物生长)

'data.frame':   30 obs. of  2 variables:
 $ weight: num  4.17 5.58 5.18 6.11 4.5 4.61 5.17 4.53 5.33 5.14 ...
 $ group : Factor w/ 3 levels "ctrl","trt1",..: 1 1 1 1 1 1 1 1 1 1 ...

您的试验不会奏效,因为您所做的只是定义变量的不同值。因此,如果您尝试str(df.empty),您将获得显示的关卡!

> str(df.empty)
'data.frame':   0 obs. of  3 variables:
 $ column1: num 
 $ column2: Factor w/ 0 levels: 
 $ column3: Factor w/ 3 levels "A","B","C"  

最后,如果你想将一行合并到一个数据框,你可以使用 rbind()

 newRow <- c(-2,"MyString","B") 
 incorrectRow <- c(-2,"MyString","C")

rbind(df.empty, newRow)
  X..2. X.MyString. X.B.
1    -2    MyString    B

rbind(df.empty, incorrectRow)
  X..2. X.MyString. X.C.
1    -2    MyString    C

它们都应该与您正常工作!

【讨论】:

  • 非常感谢!我尝试了您上面列出的代码,我看不出它与原始代码有何不同(对不起,我是新手)。
  • 无变化。我只是澄清了一切,向你展示什么是有效的!
【解决方案2】:

为了保留已定义变量的类,您必须做两件事:

1) 设置stringsAsFactors = FALSE,这样字符变量就不会成为一个因素。

2) 新行必须是列表。

就像这个例子:

> df.empty <- data.frame(column1 = numeric(), column2 = character(),
+                        column3 = factor(levels=c("A","B","C")), stringsAsFactors = FALSE)
> 
> newRow <- list(-2, "MyString","B")
> incorrectRow <- list(-2, "MyString", "C")
> 
> # Not mess columns names
> 
> df.empty[nrow(df.empty) + 1,] <- newRow
> df.empty[nrow(df.empty) + 1,] <- incorrectRow
> 
> df.empty
  column1  column2 column3
1      -2 MyString       B
2      -2 MyString       C
> summary(df.empty)
    column1     column2          column3
 Min.   :-2   Length:2           A:0    
 1st Qu.:-2   Class :character   B:1    
 Median :-2   Mode  :character   C:1    
 Mean   :-2                             
 3rd Qu.:-2                             
 Max.   :-2                             

为了保留列名,功劳归于这个anwser: https://stackoverflow.com/a/15718454/8382633

我的第一次尝试也是使用 rbind,但它有一些缺点。它不保留列名,而且,将所有字符串转换为因子,或者如果您设置 stringsAsFactors = FALSE,则将所有因子转换为字符串!!

> df.empty <- rbind.data.frame(df.empty, newRow, incorrectRow)
> 
> summary(df.empty)
   c..2...2.  c..MyString....MyString.. c..B....C..
 Min.   :-2   MyString:2                B:1        
 1st Qu.:-2                             C:1        
 Median :-2                                        
 Mean   :-2                                        
 3rd Qu.:-2                                        
 Max.   :-2                                        
> class(df.empty$c..MyString....MyString..)
[1] "factor"

或使用 stringsAsFactors = FALSE:

> df.empty <- rbind.data.frame(df.empty, newRow, incorrectRow, stringsAsFactors = FALSE)
> 
> summary(df.empty)
   c..2...2.  c..MyString....MyString.. c..B....C..       
 Min.   :-2   Length:2                  Length:2          
 1st Qu.:-2   Class :character          Class :character  
 Median :-2   Mode  :character          Mode  :character  
 Mean   :-2                                               
 3rd Qu.:-2                                               
 Max.   :-2                                               
> 
> class(df.empty$c..B....C..)
[1] "character"

我认为它接近重复。但最后,这个问题给我带来了更多的问题。

希望对你有帮助。

【讨论】:

  • 是的!所以 (levels=c("A","B","C")) 意味着第 3 列将只取值“A”、“B”或“C”,对吧?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
相关资源
最近更新 更多