如何编写循环到子集数据并重命名子样本

时间:2018-04-03 21:24:03

标签: r loops dataframe data-science

我每年都有1986 - 1995年和1997 - 2015年的全部样本。它看起来像: enter image description here 我每年也有一个变量列表,它看起来像:enter image description here

我的目的是通过在变量列表中使用变量名称将整个数据集子集化为每年的子样本数据集(第2张图片)。

我的尝试如下:

name1986 <- var_name_list$X1986
name1987 <- var_name_list$X1987
name1988 <- var_name_list$X1988
name1989 <- var_name_list$X1989
name1990 <- var_name_list$X1990
name1991 <- var_name_list$X1991
name1992 <- var_name_list$X1992
name1993 <- var_name_list$X1993
name1994 <- var_name_list$X1994
name1995 <- var_name_list$X1995
name1996 <- var_name_list$X1996
name1997 <- var_name_list$X1997
name1999 <- var_name_list$X1999
name2001 <- var_name_list$X2001
name2003 <- var_name_list$X2003
name2005 <- var_name_list$X2005
name2007 <- var_name_list$X2007
name2009 <- var_name_list$X2009
name2011 <- var_name_list$X2011
name2013 <- var_name_list$X2013
name2015 <- var_name_list$X2015

效果很好: enter image description here 但是我陷入了以下困境:

seq_yr = c(seq(1986,1996),seq(1997,2015,by=2))
for (Number in seq_yr){
  dataname <- sprintf("name",Number)
  file<- subset(data,select = c(ID,which(colnames(data) %in% dataname)))
  # assign value to the variable name x 
  assign(x=str_c("data.",Number),value=file,envir=.GlobalEnv)  
}

这成功地给了我一些子样本数据集,但每个子样本数据集只包含一个变量。这就是我工作区中的内容:

enter image description here

您能告诉我我的代码出了什么问题吗?

我想在以下链接中附上我的数据部分:

https://drive.google.com/open?id=19KMl6eNsCEfcRJxWGoyWJSb34kPhmJaW

data4是数据,header4是变量列表的一部分。

非常感谢!!!如果您对我的问题有任何疑虑,请发表评论。

1 个答案:

答案 0 :(得分:1)

从概念上讲,您要执行以下操作:

  1. 开发基础案例
  2. 将基础案例转换为函数
  3. 扩展通用解决方案
  4. 让我们来看看,但首先是一个可重复的例子:

    > df_raw <- data.frame(v1 = 1:10, v2 = 11:20, v3 = 21:30, v4 = 31:40, v5 = 41:50, v6 = 51:60)
    > 
    > df_keys <- data.frame(colNames = c('name1', 'name2', 'name3'),
    +                       year1 = c('v1', 'v2', 'v3'),
    +                       year2 = c('v4','v5','v6'))
    > 
    > 
    > df_raw
       v1 v2 v3 v4 v5 v6
    1   1 11 21 31 41 51
    2   2 12 22 32 42 52
    3   3 13 23 33 43 53
    4   4 14 24 34 44 54
    5   5 15 25 35 45 55
    6   6 16 26 36 46 56
    7   7 17 27 37 47 57
    8   8 18 28 38 48 58
    9   9 19 29 39 49 59
    10 10 20 30 40 50 60
    > df_keys
      colNames year1 year2
    1    name1    v1    v4
    2    name2    v2    v5
    3    name3    v3    v6
    

    基础案例

    始终从您的基本情况开始。创建empty data frame并将名称更改为列名称以使其可读。 df_key数据框的第一列显示变量名称,第二列显示一年年的变量名称。

    > colNames <- df_keys[,1]
    > yearNames <- df_keys[,2]
    > new_df <- data.frame(matrix(ncol = length(yearNames), nrow = 0))
    > new_df <- df_raw[,yearNames]
    > names(new_df) <- colNames
    > new_df
       name1 name2 name3
    1      1    11    21
    2      2    12    22
    3      3    13    23
    4      4    14    24
    5      5    15    25
    6      6    16    26
    7      7    17    27
    8      8    18    28
    9      9    19    29
    10    10    20    30
    

    创建一个函数

    老实说,这是最简单的一步。只需在其周围放置括号并重命名一些关键名称。

    subDF <- function(df_raw, df_keys, nameIndex = 1, yearIndex = 2){
    
      colnames <- df_keys[,nameIndex]
      yearNames <- df_keys[,yearIndex]
      new_df <- data.frame(matrix(ncol = length(yearNames), nrow = 0))
      new_df <- df_raw[,yearNames]
      names(new_df) <- colNames
      new_df
    }
    
    > subDF(df_raw, df_keys)
       name1 name2 name3
    1      1    11    21
    2      2    12    22
    3      3    13    23
    4      4    14    24
    5      5    15    25
    6      6    16    26
    7      7    17    27
    8      8    18    28
    9      9    19    29
    10    10    20    30
    

    比例

    这可以是许多方法之一。它很简单,有两个陈述。

    > allYears <- seq(dim(df_keys)[2]-1)+1
    > lapply(allyears, function(x) {subDF(df_raw, df_keys, yearIndex = x)})
    [[1]]
       name1 name2 name3
    1      1    11    21
    2      2    12    22
    3      3    13    23
    4      4    14    24
    5      5    15    25
    6      6    16    26
    7      7    17    27
    8      8    18    28
    9      9    19    29
    10    10    20    30
    
    [[2]]
       name1 name2 name3
    1      1    11    21
    2      2    12    22
    3      3    13    23
    4      4    14    24
    5      5    15    25
    6      6    16    26
    7      7    17    27
    8      8    18    28
    9      9    19    29
    10    10    20    30