【问题标题】:Is there an R function or dplyr function where you can assign values without replacement?是否有一个 R 函数或 dplyr 函数,您可以在其中分配值而无需替换?
【发布时间】:2020-04-11 09:18:48
【问题描述】:

例如,如果我有一个数据框:

v1 v2
a  1 
b  2 
c  3 
a  1
c  3

我想创建 v3,因为 v1 等于它们各自的值。 例如,如果 v1 等于 a,那么我想将“科学”分配给 v3,如果 v1 等于 b,那么我想将“数学”分配给 v3 等等。

v1 v2 v3
a  1  science
b  2  maths
c  3  english
a  1  science
c  3  english

我会以标准方式执行此操作,使用 dplyr 的 case_when 或重新编码列出许多条件,但变量中有太多唯一值,我应用条件来有效地执行此操作。

谢谢。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    你可以使用case_when

    library(dplyr)
    
    df %>%
     mutate(v3 = case_when(v1 == 'a' ~ 'science',
                           v1 == 'b' ~ 'maths', 
                           v1 == 'c' ~ 'english'))
    
    #  v1 v2      v3
    #1  a  1 science
    #2  b  2   maths
    #3  c  3 English
    #4  a  1 science
    #5  c  3 english
    

    或者创建一个参考数据框并使用merge

    ref_df <- data.frame(v1 = c('a', 'b', 'c'),v3 = c('science', 'maths', 'english'), 
                         stringsAsFactors = FALSE)
    
    merge(df, ref_df, by = 'v1')
    

    数据

    df <- structure(list(v1 = structure(c(1L, 2L, 3L, 1L, 3L), .Label = c("a", 
    "b", "c"), class = "factor"), v2 = c(1L, 2L, 3L, 1L, 3L)), 
    class = "data.frame", row.names = c(NA, -5L))
    

    【讨论】:

      【解决方案2】:

      您可以使用内置的 merge() 函数来实现这一点。更像是 sql 中的连接。 下面是一个例子

      df1 <- data.frame(v1=c("a","b","c","a","e"),v2=c(1,2,3,4,5))
      df2 <- data.frame(c1=c("a","b","c","d","e"),c2=c("maths","mechanics","biology","chemistry","physics"))
      
      df3 <- merge(df1,df2,by.x='v1',by.y='c1',all.x = TRUE)
      
      #INPUT
      #df1
      # v1 v2
      # 1  a  1
      # 2  b  2
      # 3  c  3
      # 4  a  4
      # 5  e  5
      
      #df2
      # c1        c2
      # 1  a     maths
      # 2  b mechanics
      # 3  c   biology
      # 4  d chemistry
      # 5  e   physics
      
      #df3
      # v1 v2        c2
      # 1  a  1     maths
      # 2  a  4     maths
      # 3  b  2 mechanics
      # 4  c  3   biology
      # 5  e  5   physics
      

      【讨论】:

        【解决方案3】:

        您的问题有点模棱两可,但您似乎想将字母与字母表中的等效数字相匹配。在这种情况下,您可以创建数值与其letters 匹配的factor 级别。

        .labels <- c("science", "maths", "english")
        dat$v3 <- factor(with(dat, ifelse(v1 == letters[v2], v2, NA)), 
                         labels=.labels)
        #   v1 v2      v3
        # 1  a  1 science
        # 2  b  2   maths
        # 3  c  3 english
        # 4  a  1 science
        # 5  b  4    <NA>
        # 6  c  3 english
        

        数据

        dat <- structure(list(v1 = c("a", "b", "c", "a", "b", "c"), v2 = c(1L, 
        2L, 3L, 1L, 4L, 3L)), row.names = c(NA, -6L), class = "data.frame")
        

        【讨论】:

          猜你喜欢
          • 2021-12-30
          • 2020-03-18
          • 2010-10-06
          • 1970-01-01
          • 1970-01-01
          • 2020-09-08
          • 2020-10-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多