【问题标题】:Create new column based on values in 2 other columns根据其他 2 列中的值创建新列
【发布时间】:2014-12-04 08:47:36
【问题描述】:

我是 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

我必须创建一个新列“成绩”。我需要先看年龄,然后看 GradeLevel。如果分配的 GradeLevel 正确,那么我将相同的 GradeLevel 复制到新列。如果分配的年级错误(如 obs 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").....

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

【问题讨论】:

标签: r


【解决方案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

【讨论】:

  • 可能很简单,但是 4.5 , 4 看起来有点奇怪!
  • +1 看起来很有趣,但是,我不知道您是如何修复 4.5 的。
  • @akrun 4.5 的值是年龄和水平之间有效差异的平均值(即45)。
【解决方案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))

【讨论】:

  • @Kabir 谢谢。我不确定是否需要Lowerlevel
  • 太棒了!!它起作用了,并且您使代码足够简单,以至于我可以理解。非常感谢@akrun。
猜你喜欢
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 2021-10-03
  • 2022-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多