将因子转换为R中的字符向量

时间:2020-06-14 09:02:46

标签: r dataframe casting

此刻我正在学习R,并且有一个问题,关于我何时有一个条目数量有限的因子。

我想将“ Nationality”转换为字符向量,以允许我添加多个条目,然后像以前一样将其转换回一个因子。 代码如下:


name <- c("Amy", "Bill", "Carl")
class(name)

DAD <- c(80, 65, 50)
BDA <- c(70, 50, 80.4)

gender <- as.factor(c("F", "M", "M"))
nationality <- as.factor(c("IRL", "UK", "IRL"))
age <- c(20, 21, 22)

age <- as.integer(age)
DAD <- as.integer(DAD)
BDA <- as.integer(BDA)
student <- data.frame(name, age, gender, nationality, DAD, BDA)

student$average <- as.double(as.double(student$BDA) + as.double(student$DAD))/2

#Want to break the restrictions on nationality below: 
nationality <- data.frame(lapply(nationality, as.character), stringsAsFactors=FALSE)

#Want to add these students: 
student <- rbind(student, c("Aennis", 23, "M", "FR", 55, 75, NA))
student <- rbind(student, c("Cennis", 23, "M", "SP", 55, 45, NA))

#Want to cast it back to a factor after it. 

我知道我可以只添加“ FR”和“ SP”到此完成,并且无论如何我都应该使用一个列表,但实际上我只是在玩R并尝试学习语言的语法以及如何做我想做的事,以尝试了解它们的工作原理,而不仅仅是学习解决方案!

2 个答案:

答案 0 :(得分:0)

我为您提供了将要素转化为角色的forloop程序,希望它有助于您理解转换要素。

for (col in colnames(student)) {
  if(class(student[,col])=="factor"){
    student[,col] <- as.character(levels(student[,col])[student[,col]])
  }
}

然后您可以追加额外的学生

完整代码:

name <- c("Amy", "Bill", "Carl")
class(name)

DAD <- c(80, 65, 50)
BDA <- c(70, 50, 80.4)

gender <- as.factor(c("F", "M", "M"))

#added an extra "UK"
nationality <- as.factor(c("IRL", "UK", "UK"))
age <- c(20, 21, 22)

age <- as.integer(age)
DAD <- as.integer(DAD)
BDA <- as.integer(BDA)


student <- data.frame(name, age, gender, nationality, DAD, BDA)
student$average <-  as.double(as.double(student$BDA) + as.double(student$DAD))/2

for (col in colnames(student)) {
  if(class(student[,col])=="factor"){
    student[,col] <- as.character(levels(student[,col])[student[,col]])
  }
}


#now you can add your students
student <- rbind(student, c("Aennis", 23, "M", "FR", 55, 75, NA))
student <- rbind(student, c("Cennis", 23, "M", "SP", 55, 45, NA))

#run avarage again
student$average <-  as.double(as.double(student$BDA) + as.double(student$DAD))/2

答案 1 :(得分:0)

以下方法处理了您的编辑帖子,但忽略了国籍df。计算 student $ average 会将结果转换为数字,而无需使用 as.double

我添加了@gersht的base-R版本。这是最简洁的解决方案,他应该为此而功劳。

我还添加了一个tidyverse解决方案,只是因为这是我最喜欢的方式。

name <- c("Amy", "Bill", "Carl")
class(name)
#> [1] "character"

DAD <- c(80, 65, 50)
BDA <- c(70, 50, 80.4)

gender <- as.factor(c("F", "M", "M"))
nationality <- as.factor(c("IRL", "UK", "IRL"))
age <- c(20, 21, 22)

age <- as.integer(age)
DAD <- as.integer(DAD)
BDA <- as.integer(BDA)

student <- data.frame(name, age, gender, nationality, DAD, BDA)

student$average <- (student$BDA + student$DAD) / 2

# the rbind-way ==> base-R. credit to @gersht
student <- rbind(
  student,
  `colnames<-`(data.frame("Aennis", 23, "M", "FR", 55, 75, NA), names(student))
)

student
#>     name age gender nationality DAD BDA average
#> 1    Amy  20      F         IRL  80  70    75.0
#> 2   Bill  21      M          UK  65  50    57.5
#> 3   Carl  22      M         IRL  50  80    65.0
#> 4 Aennis  23      M          FR  55  75      NA

# the tidyverse-way
library(tidyverse)
student <- student %>%
  mutate(nationality = as.character(nationality)) %>%
  add_row(
    name = "George", gender = "M", age = "44",
    nationality = "NL", BDA = 0, DAD = 5
  ) %>%
  mutate(nationality = as.factor(nationality))

student
#>     name age gender nationality DAD BDA average
#> 1    Amy  20      F         IRL  80  70    75.0
#> 2   Bill  21      M          UK  65  50    57.5
#> 3   Carl  22      M         IRL  50  80    65.0
#> 4 Aennis  23      M          FR  55  75      NA
#> 5 George  44      M          NL   5   0      NA

levels(student$nationality)
#> [1] "FR"  "IRL" "NL"  "UK"

reprex package(v0.3.0)于2020-06-14创建