根据其他2列中的值创建新列

时间:2014-10-09 12:11:47

标签: r

我是R的新手,我正在尝试根据数据框中的其他2列创建新列。

UserID    Age    GradeLevel
 001       10       5
 002       10       3
 003       8        4
 004       10       7
 005       8        3
 006       8        NA
 007       10       6
 008       7        NA
 009       7        6

我必须创建一个新列“Grade”。我需要先看看年龄,然后再看看GradeLevel。如果指定的GradeLevel正确,则将相同的GradeLevel复制到新列。如果指定的成绩水平是错误的(如在障碍2,4,6,8,9中),那么我必须根据年龄将用户分配到更高的等级。

例如,10岁的孩子可以是5年级或6年级,但如果GradeLevel不是5或6,则分配到6年级(2年级更高)。

所以期望的输出应该是这样的:

UserID    Age    GradeLevel    Grade
 001       10       5            5
 002       10       3            6
 003       8        4            4
 004       10       7            6
 005       8        3            3
 006       8        NA           4
 007       10       6            6
 008       7        NA           3
 009       7        6            3

GradeLevel是数据中的一个因素,但如果需要,我们可以将其转换为字符。在数据中,我有从K到12的所有GradeLevels。 我正在尝试使用ifelse语句,但无法使其工作。

test$Grade.f = ifelse(test$age==10 & (test$GradeLevel %in% c(5,6)), test$GradeLevel, "6")
               ifelse(test$age==9 & (test$GradeLevel %in% c(4,5)), test$GradeLevel, "5").....

我需要一些帮助来解决这个问题。

2 个答案:

答案 0 :(得分:2)

可能有帮助:

df1 <- data.frame(Age=10:7, Lowerlevel=5:2, Upperlevel=6:3)
library(dplyr)
res <- left_join(df,df1, by="Age")
 df$Grade <- with(res, ifelse(is.na(GradeLevel)|GradeLevel< Lowerlevel|GradeLevel>Upperlevel,
                          Upperlevel, GradeLevel))
 df
 #  UserID Age GradeLevel Grade
 #1      1  10          5     5
 #2      2  10          3     6
 #3      3   8          4     4
 #4      4  10          7     6
 #5      5   8          3     3
 #6      6   8         NA     4
 #7      7  10          6     6
 #8      8   7         NA     3
 #9      9   7          6     3

数据

df <- structure(list(UserID = 1:9, Age = c(10L, 10L, 8L, 10L, 8L, 8L, 
10L, 7L, 7L), GradeLevel = c(5L, 3L, 4L, 7L, 3L, NA, 6L, NA, 
6L)), .Names = c("UserID", "Age", "GradeLevel"), class = "data.frame", row.names = c(NA, 
-9L))

答案 1 :(得分:1)

另一种简单方法:

# identify invalid values
invalid <- with(test, abs(Age - 4.5 - "[<-"(GradeLevel, is.na(GradeLevel), 0)) > 0.5)

# replace invalid values with default values
test$Grade <- ifelse(invalid, test$Age - 4, test$GradeLevel)

test
#   UserID Age GradeLevel Grade
# 1    001  10          5     5
# 2    002  10          3     6
# 3    003   8          4     4
# 4    004  10          7     6
# 5    005   8          3     3
# 6    006   8         NA     4
# 7    007  10          6     6
# 8    008   7         NA     3
# 9    009   7          6     3