此刻我正在学习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并尝试学习语言的语法以及如何做我想做的事,以尝试了解它们的工作原理,而不仅仅是学习解决方案!
答案 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创建