根据R中的条件删除数据框列

时间:2016-01-20 14:31:38

标签: r dataframe data.table multiple-columns

我必须删除数据框中有超过4000列和180行的列。我想设置的条件是删除数据框中的列: (i)如果该列中的值/条目少于两个,则删除该列 (ii)如果没有连续两个(一个接一个),删除该列 列中的值。 (iii)移除所有值为NA的列。 我提供了要删除列的条件。这里的目的不仅仅是在名称中找到一个列,如"如何删除data.table中的列?"。 我说明如下:

A       B    C   D  E
0.018  NA    NA  NA NA
0.017  NA    NA  NA NA
0.019  NA    NA  NA NA
0.018  0.034 NA  NA NA
0.018  NA    NA  NA NA
0.015  NA    NA  NA 0.037
0.016  NA    NA  NA 0.031
0.019  NA    0.4 NA 0.025
0.016  0.03  NA  NA 0.035
0.018  NA    NA  NA 0.035
0.017  NA    NA  NA 0.043
0.023  NA    NA  NA 0.040
0.022  NA    NA  NA 0.042

所需数据框:

A       E
0.018   NA
0.017   NA
0.019   NA
0.018   NA
0.018   NA
0.015   0.037
0.016   0.031
0.019   0.025
0.016   0.035
0.018   0.035
0.017   0.043
0.023   0.040
0.022   0.042

如何在一个代码中包含这三个条件。在这方面,我将非常感谢你的帮助。 可重复的例子

structure(list(Month = c("Jan-2000", "Feb-2000", "Mar-2000", 
"Apr-2000", "May-2000", "Jun-2000"), A.G.L.SJ.INVS...LON..DEAD...13.08.15 = c(NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), ABACUS.GROUP.DEAD...18.02.09 = c(0.00829384766220866, 
0.00332213653674028, 0, 0, NA, NA), ABB.R..IRS. = c(NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_)), .Names = c("Month", 
"A.G.L.SJ.INVS...LON..DEAD...13.08.15", "ABACUS.GROUP.DEAD...18.02.09", 
"ABB.R..IRS."), class = c("data.table", "data.frame"), row.names = c(NA, 
-6L), .internal.selfref = <pointer: 0x0000000001c90788>)

2 个答案:

答案 0 :(得分:5)

我觉得这太复杂了。条件2已包含所有其他条件,就好像列中至少有两个非NA值,显然整列不是NA s。如果列中至少有两个连续值,那么这个列显然包含多个值。因此,而不是3个条件,这一切都归结为一个条件(我不希望每列运行许多函数,而是在每列运行diff之后 - 完成整个事情):

cond <- colSums(is.na(sapply(df, diff))) < nrow(df) - 1

这是有效的,因为如果列中没有连续值,则整列将变为NA s。

然后,只是

df[, cond, drop = FALSE]
#        A     E
# 1  0.018    NA
# 2  0.017    NA
# 3  0.019    NA
# 4  0.018    NA
# 5  0.018    NA
# 6  0.015 0.037
# 7  0.016 0.031
# 8  0.019 0.025
# 9  0.016 0.035
# 10 0.018 0.035
# 11 0.017 0.043
# 12 0.023 0.040
# 13 0.022 0.042

根据您的修改,您似乎拥有data.table个对象,并且还有一个Date列,因此代码需要进行一些修改。

cond <- df[, lapply(.SD, function(x) sum(is.na(diff(x)))) < .N - 1, .SDcols = -1] 
df[, c(TRUE, cond), with = FALSE]

一些解释:

  • 我们希望忽略计算中的第一列,因此我们在.SDcols = -1上操作时指定.SD(这意味着 S ub D data.table中的ata是)
  • .N只是行数(类似于nrow(df)
  • 下一步是按条件子集。我们也不必忘记抓住第一列,所以我们从c(TRUE,...
  • 开始
  • 最后,data.table默认使用非标准评估,因此,如果您想要在data.frame中选择列,则需要指定with = FALSE

更好的方法是使用:= NULL

删除引用列
cond <- c(FALSE, df[, lapply(.SD, function(x) sum(is.na(diff(x)))) == .N - 1, .SDcols = -1])
df[, which(cond) := NULL]

答案 1 :(得分:4)

为每个条件创建逻辑向量:

# condition 1
cond1 <- sapply(df, function(col) sum(!is.na(col)) < 2)

# condition 2
cond2 <- sapply(df, function(col) !any(diff(which(!is.na(col))) == 1))

# condition 3
cond3 <- sapply(df, function(col) all(is.na(col)))

然后将它们组合成一个面具:

mask <- !(cond1 | cond2 | cond3)

> df[,mask,drop=F]
       A     E
1  0.018    NA
2  0.017    NA
3  0.019    NA
4  0.018    NA
5  0.018    NA
6  0.015 0.037
7  0.016 0.031
8  0.019 0.025
9  0.016 0.035
10 0.018 0.035
11 0.017 0.043
12 0.023 0.040
13 0.022 0.042