2016-01-20 82 views
1

我必須刪除我的數據幀中有4000列和180行的列。我想設置的條件以刪除數據幀中的列: (i)刪除(ii)如果列中沒有兩個連續的(一個接一個) 值,則移除該列(如果該列中的值不足兩個值/條目) 。 (iii)刪除所有值爲NA的列。 我已經提供了要刪除列的條件。這裏的目的不僅僅在於如何在「如何刪除data.table中的列」中找到其名稱的列。 我舉例說明如下:基於R中的條件刪除數據幀的列

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 

我怎樣才能在一個代碼incoporate這三個條件。我很感謝你在這方面的幫助。 重複的例子,

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>) 
+0

對於(I)以除去柱:'DF [,sapply(DF,函數(x)的sum(!is.na(x))> 1)]' – jogo

+0

@Frank這裏刪除列是根據條件而不是名稱。 – Aquarius

+0

@Aquarius在鏈接q中,這些也是條件。它們只是基於名稱而非價值向量的條件。我不認爲它本質上不同。我也認爲目標鏈接是有幫助的,因爲它顯示':= NULL',這是如何通過引用刪除列(而不是創建一個全新的表)。 – Frank

回答

4

我覺得這一切都是過於複雜。條件2已經包括了所有其餘的條件,就好像在一列中至少有兩個非值,顯然整列不是NAs。如果一列中至少有兩個連續值,那麼顯然這一列包含多個值。因此,而不是3個條件,這一切都總結了成一個單一的條件(我不喜歡跑每列的許多功能,而運行diff每列〜vecotrize整個事情後):

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

這工作,因爲如果有在一列中沒有連續的值,整列將變爲NAs。

然後,就

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(這意味着小號 UB d ATA在data.table是)
  • .N只是行數(類似於nrow(df)
  • 下一步是按條件子集。我們不必忘記抓住第一列,所以我們開始c(TRUE,...
  • 最後,data.table默認使用非標準評估,

雖然一種更好的方式,將僅僅通過參考使用:= NULL

cond <- c(FALSE, df[, lapply(.SD, function(x) sum(is.na(diff(x)))) == .N - 1, .SDcols = -1]) 
df[, which(cond) := NULL] 
+0

讓我們[在聊天中繼續討論](http://chat.stackoverflow.com/rooms/101301/discussion-between-aquarius-and-david-arenburg)。 – Aquarius

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 
+0

僅供參考,你只需要這裏的條件2,它可以簡化爲'cond2 < - sapply(df,function(col)any(!is.na(diff(col))))'你就可以走了。所有其他條件都是多餘的。 –

+2

OP對於R來說似乎是新的,所以我選擇了一個更清晰,如果多餘的答案,希望能夠展示一種在未來可能有用的模式。雖然條件可以結合在這個例子中,但情況並非總是如此。 – Zelazny7

+0

我承擔提供低效信息來執行這項任務的全部責任。我是新來的,對軟件沒有經驗。我很抱歉,但答案2最符合我的要求。我希望你能理解。 – Aquarius