【问题标题】:Replace values from a column with value corresponding to vector with matches用匹配向量对应的值替换列中的值
【发布时间】:2020-10-02 09:49:20
【问题描述】:

我有一个数据框,在“角色”列中,每一行都有一个“学生”或“老师”的值。我想相应地用“st”或“te”替换这些值。

roles_complete <- c("students","teacher")
roles_standard <- c("st", "te")
data$roles <- stri_replace_all(data$roles, regex= roles_complete, roles_standard)

奇怪的是,这只改变了一些值。

    roles
1   st
2   students
3   teacher
4   te
5   st
6   students
7   teacher
8   te
9   st
10  students
11  teacher
12  te

我在 stri_replace 中插入的条件显然有问题,但文档不是很清楚。

【问题讨论】:

    标签: r string dataframe replace str-replace


    【解决方案1】:

    dplyr

    您可以在dplyr 中使用recode()

    library(dplyr)
    
    df %>%
      mutate(roles = recode(roles, "students" = "st", "teacher" = "te"))
    

    如果您为变量分配了角色,那么您可以将命名向量作为输入。

    roles_complete <- c("students", "teacher")
    roles_standard <- c("st", "te")
    
    df %>%
      mutate(roles = recode(roles, !!!setNames(roles_standard, roles_complete)))
    

    stringr

    stringr 中的str_replace_all() 也可以将命名向量作为输入。

    library(stringr)
    
    df$roles <- str_replace_all(df$roles, setNames(roles_standard, roles_complete))
    

    base解决方案

    df$role <- factor(df$role, labels = c("st", "te"))
    

    【讨论】:

    • 我使用了带有命名向量的解决方案作为输入!非常感谢
    【解决方案2】:

    通常 R 将字符向量解释为因子。如果您的数据集中是这种情况:

    data <- data.frame(roles = sample(c("students","teacher"), 12, replace = TRUE))
    levels(data$roles)
    # [1] "students" "teacher" 
    levels(data$roles) <- c("st", "te")
    levels(data$roles)
    # [1] "st" "te"
    

    【讨论】:

      【解决方案3】:

      那是stringi 包吗?在我看来,只有连续的“学生”和“老师”的序列(向量)被替换。所以当连续有“学生”和“学生”时,它保持不变。

      如果您可以切换到包stringr,则函数str_replace_all() 允许您准确定义如何替换匹配的模式:

      library(stringr)
      data <- c("students", "teacher", "students", "teacher")
      str_replace_all(data, c("students" = "st", "teacher" = "te"))
      

      所以对于你的情况:

      data$roles <- str_replace_all(data$roles, c("students" = "st", "teacher" = "te"))
      

      【讨论】:

      • 不幸的是,这只是一个测试运行脚本,实际使用将替换 31 个不同的唯一值。有没有其他方法可以将所有 31 场比赛都写在那里?
      • @AarónGzz 肯定会有一些解决方案!但我需要问:你的意思是自动为 31 个唯一值创建一个命名向量吗?或者我可以只将所有值缩短为 2 个字符?
      • 谢谢彼得。我最终创建了一个包含所有 31 个唯一值的向量,然后使用 setNames() 输入 recode()。
      • 太好了,@AarónGzz,感谢您的反馈,您的最终解决方案非常优雅和简单!
      【解决方案4】:

      最简单的 Base R 方法,假设每个级别是学生或教师,如 OP 中所述:

      levels(data$roles) <- substr(levels(data$roles), 1, 2)
      

      数据

      data <-
        data.frame(roles = sample(c("students", "teacher"), 12, replace = TRUE))
      

      【讨论】:

        【解决方案5】:

        你可以试试

        data$roles <- replace(data$roles,roles_complete,roles_standard)
        

        【讨论】:

        • 我认为replace() 不能那样工作。你确定你的代码在你的电脑上是可行的吗?
        • @Darren Tsai,它在我的测试中有效。我使用字符串作为输入。目前尚不清楚数据是否是一个因素。
        • 你能帮我试试这个例子吗? data &lt;- data.frame(roles = rep(c("students","teacher"), 2), stringsAsFactors = F)。谢谢
        • replace() 返回一个长度为 6 的向量,但我的示例数据只有 4 行。
        猜你喜欢
        • 2017-07-19
        • 2020-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-03
        • 2020-09-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多