【问题标题】:How to do a complex edit of columns of all data frames in a list?如何对列表中所有数据框的列进行复杂编辑?
【发布时间】:2018-08-04 21:08:15
【问题描述】:

我有一个包含 185 个数据框的列表,名为 WaFramesNumeric。每个数据框都有数百列和数千行。我想编辑每个数据框,以便它保留所有数字列以及我指定的任何非数字列。

使用:

for(i in seq_along(WaFramesNumeric)) {
    WaFramesNumeric[[i]] <- WaFramesNumeric[[i]][,sapply(WaFramesNumeric[[i]],is.numeric)] 
}

成功地使每个数据框只包含其数字列。

我尝试用行来修改它以添加特定的列。我试过了:

for (i in seq_along(WaFramesNumeric)) {
    a <- WaFramesNumeric[[i]]$Device_Name
    WaFramesNumeric[[i]] <- WaFramesNumeric[[i]][,sapply(WaFramesNumeric[[i]],is.numeric)] 
    cbind(WaFramesNumeric[[i]],a)
}

并试图调用所有整数列的列号以及特定的列号,然后基于此进行组合:

for (i in seq_along(WaFramesNumeric)) {
    f <- which(sapply(WaFramesNumeric[[i]],is.numeric))
    m <- match("Cost_Center",colnames(WaFramesNumeric[[i]]))
    n <- match("Device_Name",colnames(WaFramesNumeric[[i]]))
    combine <- c(f,m,n)
    WaFramesNumeric[[i]][,i,combine]
}

这些都返回错误,我不知道该怎么做。 WaFramesNumeric 是另一个数据框列表 (WaFramesNumeric &lt;- WaFramesAll) 的副本,因此我也尝试从 WaFramesAll 添加特定列,但这并不成功。

感谢您提供的任何建议,如果有任何不清楚之处,我深表歉意。

【问题讨论】:

  • 您对WaFramesNumeric[[i]][,i,combine] 的双逗号索引有何期待?据我所知,您使用combine 填充的位置仅用于drop=exact=,而不是整数位置。另外,如果i 引用列表中的特定data.frame,为什么要在内部data.frame 索引中使用它?我认为它只是WaFramesNumeric[[i]][,combine]
  • @r2evans 老实说,我是 R 的新手,我一直在研究这个特定问题很长时间。那是当我收到我没有指定列的错误时。我确实犯了一些错误,但我只是想在提问时展示我的思考过程。理想情况下,第一行可以添加几行以指定将列添加到仅是数字列的新框架中。

标签: r list dataframe integer multiple-columns


【解决方案1】:

您错误地认为for 循环中的最后一个命令是有意义的。它不是。实际上,它正在被丢弃,因此由于您从未将其分配到任何地方(cbindWaFramesNumeric... 的索引),因此它会被静默丢弃。

此外,您在第三个代码块中过度索引 data.frame。首先,它在data.frame 中使用i,即使i 是data.frames 的list 中的索引,而不是框架本身。其次(可能是由此引起的),您正在尝试索引二维帧的三个维度。只需将最后一个索引从 [,i,combine] 更改为 [,combine][combine]

第三个问题(虽然可能还没有看到)是如果没有找到,match 将返回NA。使用NA 索引框架会返回错误(尝试mtcars[,NA] 来查看)。我建议您可以将match 替换为grep:当没有找到任何内容时,它会返回integer(0),这就是您在这种情况下想要的。

for (i in seq_along(WaFramesNumeric)) {
  f <- which(sapply(WaFramesNumeric[[i]], is.numeric))
  m <- grep("Cost_Center", colnames(WaFramesNumeric[[i]]))
  n <- grep("Device_Name", colnames(WaFramesNumeric[[i]]))
  combine <- c(f,m,n)
  WaFramesNumeric[[i]] <- WaFramesNumeric[[i]][combine]
}

【讨论】:

  • 感谢您的澄清。我确实认为循环中的一切都按顺序发生,并且根本没有意识到这被丢弃了。我运行了这个,但结果与我的 for(i in seq_along(WaFramesNumeric)){ WaFramesNumeric[[i]] &lt;- WaFramesNumeric[[i]][,sapply(WaFramesNumeric[[i]],is.numeric)] } 行相同。那么这是否意味着它忽略了我想要包含"Cost_Center"Device_Name" 这两个非数字列的部分?
  • 编辑:我尝试了不同的途径,但grep 和你的例子是不可或缺的,所以,再次,非常感谢!它就像一个魅力。
【解决方案2】:

我不确定您所说的“尝试调用所有整数列的列号...”是什么意思,但如果您想浏览数据框列表并根据某些函数选择一些列并保持给定一个列名,您可以这样做:

df <- data.frame(a=rnorm(20), b=rnorm(20), c=letters[1:20], d=letters[1:20], stringsAsFactors = FALSE)
WaFramesNumeric <- rep(list(df), 2)

Selector <- function(data, select_func, select_names) {
  select_func <- match.fun(select_func)
  idx_names <- match(select_names, colnames(data))
  idx_names <- idx_names[!is.na(idx_names)]
  idx_func <- which(sapply(data, select_func))
  idx <- unique(c(idx_func, idx_names))
  return(data[, idx])
}

res <- lapply(X = WaFramesNumeric, FUN = Selector, select_names=c("c"), select_func = is.numeric)

【讨论】:

  • 抱歉不清楚。我试图通过循环来解决我的问题,为任何数字列和我指定的任何其他列调用数据框的列号。然后我将使用列号作为参考,通过绑定来替换框架。但是谢谢你,它确实有帮助!我试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-21
  • 1970-01-01
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
  • 2017-05-21
  • 1970-01-01
相关资源
最近更新 更多