【问题标题】:How to recode multiple variables for a subset of a dataframe?如何为数据框的子集重新编码多个变量?
【发布时间】:2020-04-11 02:46:31
【问题描述】:

我迷路了,所以任何方向都会有所帮助。假设我有一个数据框:

df <- data.frame(
  id = 1:12,
  v1 = rep(c(1:4), 3),
  v2 = rep(c(1:3), 4),
  v3 = rep(c(1:6), 2),
  v4 = rep(c(1:2), 6))

我的目标是为变量 v3 和 v4 重新编码 2=4 和 4=2,但仅针对前 4 种情况(id

【问题讨论】:

    标签: r dataframe recode


    【解决方案1】:

    这是一个基本的 R 解决方案,

    df[1:5, c('v3', 'v4')] <- lapply(df[1:5, c('v3', 'v4')], function(i) 
                                           ifelse(i == 2, 4, ifelse(i == 4, 2, i)))
    

    给出,

       id v1 v2 v3 v4
    1   1  1  1  1  1
    2   2  2  2  4  4
    3   3  3  3  3  1
    4   4  4  1  2  4
    5   5  1  2  5  1
    6   6  2  3  6  2
    7   7  3  1  1  1
    8   8  4  2  2  2
    9   9  1  3  3  1
    10 10  2  1  4  2
    11 11  3  2  5  1
    12 12  4  3  6  2
    

    【讨论】:

    • 也谢谢。我认为了解解决方案的基本 R 版本非常有用!
    • 或df[1:5, c('v3', 'v4')][df[1:5, c('v3', 'v4')] == 2 | df[1:5, c('v3', 'v4')] == 4] &lt;- 6-df[1:5, c('v3', 'v4')][df[1:5, c('v3', 'v4')] == 2 | df[1:5, c('v3', 'v4')] == 4](可以用索引缩短...)
    • @Cath 你应该把它放在一个新的答案中!
    【解决方案2】:

    您可以在dplyr 中尝试mutate_at 和case_when

    library(dplyr)
    
    df %>%
      mutate_at(vars(v3:v4), ~case_when(id < 5 & . == 4 ~ 2L, 
                                        id < 5 & . == 2 ~ 4L, 
                                        TRUE ~.))
    #   id v1 v2 v3 v4
    #1   1  1  1  1  1
    #2   2  2  2  4  4
    #3   3  3  3  3  1
    #4   4  4  1  2  4
    #5   5  1  2  5  1
    #6   6  2  3  6  2
    #7   7  3  1  1  1
    #8   8  4  2  2  2
    #9   9  1  3  3  1
    #10 10  2  1  4  2
    #11 11  3  2  5  1
    #12 12  4  3  6  2
    

    使用mutate_at,您可以指定要应用该函数的列范围。

    【讨论】:

    • 好的,谢谢!这看起来是一个不错的解决方案。我不太明白的是“~”和“。”的用法。在这里,所以我并没有真正看到“TRUE〜”的作用。在末尾。点的工作方式类似于通过变量的循环?
    • @2freet TRUE ~ . 最后指的是列不是 4 或 2 的所有情况,因此在这种情况下它保持相同的值。 ~ 是一种公式样式的语法,您可以在 ?case_when 阅读更多相关信息。
    【解决方案3】:

    另一个更直接的选择是获取要替换的数字的索引,并将它们替换为 6 减去数字(6-4=2, 6-2=4):

    whToChange <- which(df[1:5, c("v3", "v4")] ==2 | df[1:5, c("v3", "v4")]==4, arr.ind=TRUE)
    
    df[, c("v3", "v4")][whToChange] <- 6-df[, c("v3", "v4")][whToChange]
    
    head(df, 5)
    #  id v1 v2 v3 v4
    #1  1  1  1  1  1
    #2  2  2  2  4  4
    #3  3  3  3  3  1
    #4  4  4  1  2  4
    #5  5  1  2  5  1
    

    【讨论】:

      【解决方案4】:

      您可以使用match 和一个查找表 - 只是为了追逐,您必须后退两个以上的值。

      rosetta <- matrix(c(2,4,4,2), 2)
      df[1:4, c("v3", "v4")] <- lapply(df[1:4, c("v3", "v4")], function(x) {
        i <- match(x, rosetta[1,]); j <- !is.na(i); "[<-"(x, j, rosetta[2, i[j]])})
      df
      #   id v1 v2 v3 v4
      #1   1  1  1  1  1
      #2   2  2  2  4  4
      #3   3  3  3  3  1
      #4   4  4  1  2  4
      #5   5  1  2  5  1
      #6   6  2  3  6  2
      #7   7  3  1  1  1
      #8   8  4  2  2  2
      #9   9  1  3  3  1
      #10 10  2  1  4  2
      #11 11  3  2  5  1
      #12 12  4  3  6  2
      

      也可以看看R: How to recode multiple variables at once 或Recoding multiple variables in R

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-28
        • 1970-01-01
        • 2016-11-05
        • 1970-01-01
        • 1970-01-01
        • 2021-07-08
        • 1970-01-01
        • 2018-07-18
        相关资源
        最近更新 更多