【问题标题】:Using similar variable names in R, split/subset a large dataframe into multiple smaller ones在 R 中使用相似的变量名称,将大数据帧拆分/子集为多个较小的数据帧
【发布时间】:2019-02-10 18:47:53
【问题描述】:

我有一个包含 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. 此外,我认为应用程序家族必须有一个更优雅的解决方案。有什么想法吗?

非常感谢您的帮助。

【问题讨论】:

  • 你需要lst1 &lt;- lapply(my.list, function(x) cbind(my.data[1:2], my.data[grep(x, names(my.data))])); names(lst1) &lt;- paste0("newdata", my.list); list2env(lst1, envir = .GlobalEnv)还是splitsplit.default(my.data[-(1:2)], sub(".*_", "", names(my.data)[-(1:2)]))
  • 嗨@akrun,非常感谢。第一个做我需要的!有没有办法在每个数据框中创建所有变量? (意思是在 1998 年的数据框中也有 z,所有值都是 NA?)

标签: r


【解决方案1】:

我们可以使用循环遍历'my.list',使用grep提取与'my.list'中的子串匹配的列名,cbind与前两列创建listdata.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 的data.frames


或者另一个选项是 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) 

【讨论】:

  • 嗨@akrun,非常感谢。我遵循在大数据中创建 NA 列的代码,然后使用 grep 代码,这正是我需要做的。我也做了拆分位,这给出了同样的结果..为什么将它保存在列表中更好?
  • @econbuffin2019 1) 列表中的所有操作更容易完成。 2)在全局环境中拥有大量对象不是一个好主意,3)如果您已对所有对象进行了所有操作并想要保存对象,那么您可能需要将其带回列表以保存每个对象作为一个单独的文件或一个一个保存(当有更多对象时很难)
  • 感谢您的解释。我明白你的意思。会记住的。在这种情况下,我不需要做类似的操作,但我看看如果我必须这样做,它会更好。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 2021-10-10
  • 2014-12-02
  • 2020-12-14
  • 2021-11-08
  • 2020-10-06
  • 2022-01-24
  • 2013-11-16
相关资源
最近更新 更多