【问题标题】:Paste variable names in a function R在函数 R 中粘贴变量名
【发布时间】:2021-08-10 13:49:20
【问题描述】:

我需要通过以下方式转换数据框:

year1 <- rep(2001, 5)
b <- c("","","120","","131")
d <- c(letters[1:5])
year2 <- c("","","2002","","2004")

dat <- data.frame(cbind(a,d,year1,b,year2))
dat 

    a d year1   b year2
1 249 a  2001          
2 234 b  2001          
3 273 c  2001 120  2002
4 201 d  2001          
5 238 e  2001 131  2004

这是下面所需的输出。基本上,我需要将 b 和 year 2 中的值移到 a 和 year 1 下,并重复此记录的所有其他信息。

    a d year1    b year2 id
1 249 a  2001             1
2 234 b  2001             2
3 273 c  2001  120  2002  3
4 201 d  2001             4
5 238 e  2001  131  2004  5
6 120 c  2002 <NA>  <NA>  3
7 131 e  2004 <NA>  <NA>  5 

我写了一个函数,因为我需要在多个数据集上做同样的事情。这是我的问题:列名可能会有所不同。如何改进下面的功能,以便我可以更改输入中列的名称。我已经在需要帮助的地方做了标记。

下面是我的方法:

fix_records <- function(dat=dat, event1=c("a","year1"), event2 = c("b","year2")) {
dat$id <- 1:nrow(dat)
dat1 <- dat[ , -which(names(dat) %in% event1)] 
dat2 <- dat1[which(dat1$year2!=""),] # NEED HELP HERE: how to pass year2 in a generic way? 
names(dat2) <- c("d", "a", "year1", "id") # Is there a way to link this line to the arguments? 
dat3 <- dplyr::bind_rows(dat, dat2)
return(dat3)
}

【问题讨论】:

    标签: r function arguments


    【解决方案1】:

    你可以使用dplyr:

    library(dplyr)
    
    fix_records <- function(df, event1 = c("a", "year1"), event2 = c("b", "year2")) {
      
      df <- df %>%
        mutate(id = row_number()) 
      
      df %>% 
        filter(!!sym(event2[2]) != "") %>% 
        select(
          id,
          d,
          !!sym(event1[1]) := !!sym(event2[1]),
          !!sym(event1[2]) := !!sym(event2[2])
          ) %>% 
        bind_rows(df, .)
    }
    
    fix_records(df)
    
    #>     a d year1    b year2 id
    #> 1 249 a  2001             1
    #> 2 234 b  2001             2
    #> 3 273 c  2001  120  2002  3
    #> 4 201 d  2001             4
    #> 5 238 e  2001  131  2004  5
    #> 6 120 c  2002 <NA>  <NA>  3
    #> 7 131 e  2004 <NA>  <NA>  5
    

    【讨论】:

    • 谢谢。这很好用,感谢您的帮助。
    【解决方案2】:

    您可以使用数据表而不是数据框。

    library(data.table)
    
    a <- c("249", "234", "273", "201", "238")
    year1 <- rep("2001", 5)
    b <- c("","","120","","131")
    d <- c(letters[1:5])
    year2 <- c("","","2002","","2004")
    dat <- data.table(a, d, year1, b, year2)
    
    fix_records <- function(dat, event1 = c("a", "year1"), event2 = c("b", "year2")) {
      col_name <- setdiff(names(dat), c(event1, event2))
      dat$id <- 1:nrow(dat)
      dat2 <- dat[get(event2[2]) != "", ]
      dat2 <- dat2[, (event1) := NULL]
      names(dat2) <- c(col_name, event1, "id")
      dat3 <- dplyr::bind_rows(dat, dat2)
      return(dat3)
    }
    

    【讨论】:

    • 谢谢,这个解决方案效果很好,感谢您的帮助
    猜你喜欢
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    相关资源
    最近更新 更多