在R中使用类似的变量名,将一个大数据帧拆分/子集为多个较小的数据帧

时间:2019-02-10 18:47:53

标签: r

我有一个数据集,该数据集具有以下300个变量:

创建示例数据:

id <- c('a','b','c', 'd', 'e', 'f')
type <- c(1,2,3,1,2,3)
x_97 <- c(1,2,3,4,5,6)
y_97 <- c('q','w','r','t', 'y', 'i')
z_97 <- c(80,90,70,50,60,40)
x_98 <- c(7,8,9,4,5,6)
y_98 <- c('y', 'i', 'r','t','q','w')
x_99 <- c(4,5,5,6,1,2)
z_99 <- c(20,10,40,50,20,50)
w_99 <- c(8,9,7,4,5,NA)
my.data <- data.frame(id, type, x_97, y_97, z_97, x_98, y_98, x_99, z_99)

请注意:_97,_98,_99是1997、1998和1999年。

预期结果:

我想根据id和type每年将这个大数据帧分成3个较小的数据帧。

最初的想法:

我正在创建一个列表:

my.list <- c("_97", "_98", "_99") 

现在我要写这样的东西:

newdata97 <- subset(my.data, all variables with the 1st object of my.list)
newdata98 <- subset(my.data, all variables with the 2nd object of my.list)

以此类推。

问题

  1. 我不确定如何实现上述新数据框架。谁能帮忙吗?
  2. 此外,我认为应用家庭提供了一些更优雅的解决方案。有什么想法吗?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我们可以使用“ my.list”循环,使用grep提取与“ my.list”中的子字符串相匹配的列名,cbind与前两列创建一个list中的data.frames

lst1 <- lapply(my.list, function(x) cbind(my.data[1:2], 
     my.data[grep(x, names(my.data))]))

如果缺少“ x”,“ y”,“ z”之间的列之一,则可以将其分配给NA

lst1 <-  lapply(lst1, function(x)  {nm1 <- setdiff(paste0(c('x', 'y', 
 'z'),  substring(names(x)[3], 2)), names(x)[-(1:2)]); x[nm1] <- NA; x})

或者以后不要创建列,而是在“ my.data”中创建NA列

my.data[setdiff(paste0(rep(c("x_", "y_", "z_"), each = 3), 
       97:99), names(my.data)[-(1:2)])] <- NA

然后使用上述的grep来创建list的数据帧。


或者另一个选择是基于列名称的子字符串split

lst1 <- lapply(split.default(my.data[-(1:2)], 
   sub(".*_", "", names(my.data)[-(1:2)])), function(x) cbind(my.data[1:2], x))

最好将其保留为list,但是如果我们在全局环境中需要单独的data.frames,请命名list元素并使用list2env(尽管不建议这样做)

names(lst1) <- paste0("newdata", substring(my.list, 2))
list2env(lst1, envir = .GlobalEnv)