2016-07-04 74 views
0

我有數據框tab1 - 想象它有10行和50列,包括下面的工作結果。grep +循環應用於數據幀

我想在tab1的每個字段中搜索字符串morse。我也想爲每一行做這個。 我的確得到與下面的代碼工作的結果,但有兩件事情我不明白,我已經把代碼的下方

tab1$str<-NA 
for(i in 1:10) { 
    str<-grep("morse", tab1[i,], ignore.case=TRUE) 
    tab1$str[i] <- str 
} 

Error in tab1$str[i] <- str : replacement has length zero 

tab1$str 
[1] 44 NA NA NA NA NA NA NA NA NA   

##the first row, column44 did indeed contain the string, whilst the others did not. 

問題:

  1. 爲什麼需要第一行? tab1$str <- NA。如果沒有這個, 結果是錯誤的,即使它們不包含字符串morse,矢量tab1$str的每個值都是 44。
  2. 爲什麼我會收到錯誤消息,即使結果是 正確?

通常,我不是一個編碼器,並認爲這應該是簡單的,如果我遞歸地指定行。

非常感謝您的幫助。

回答

0

從你的問題來看,它不是真正清楚你在找什麼,但也許你可以使用apply系列完全避免循環。有了這個模擬數據:

tab1 <- data.frame(a=sample(c("morse", "other", "foo", "top"), 10, replace = T), b = sample(c("morse", "other", "foo", "top"), 10, replace = T), c = sample(c("morse", "other", "foo", "top"), 10, replace = T)) 

下面的函數爲每一行返回一個列表元素,並顯示哪一列有一個「莫爾斯」條目。

apply(tab1,1, function(x) grep("morse",x)) 
+0

......這正是我期待做的 - 我還沒有完全理解它,但它得到了我正在尋找的結果。非常感謝,抱歉,還沒有足夠的積分來回答你的答案。 – James

+0

很高興提供幫助。使用'應用函數r'搜索可能會對您有所幫助。您仍然可以通過點擊答案旁邊的複選標記來接受最有幫助的答案。 –

0

回答您的問題:

  1. 您需要tab1$str <- NA初始化,你在爲grep()計算的每遍for循環添加元素進行迭代的列表(數據幀的列)。
  2. 錯誤消息是因爲grep()在某個迭代中返回一個NULL值或logical(0),這是一個未定義的沒有長度的值,因此不能分配給向量的元素。

但是,因爲你是分配給一個數據幀嵌套列表,你不邏輯檢查的NULLgrep()回報您上面的方法是不是最佳的。

考慮使用sapply()ifelse()的矢量化方法,該方法將返回一個矩陣,該矩陣等於遞歸檢查每列和每行的數據幀的維數。低於grep()返回列中的「Morse」值的行索引。

morse_matrix <- sapply(df, function(x) ifelse(grepl("Morse", x), grep("Morse", x), NA)) 

morse_list <- sapply(df, function(x) ifelse(grep("Morse", x), grep("Morse", x), NA)) 

morse_df <- data.frame(morse_matrix) 
+0

'grepl'可能比不必擔心'NULL'值更合適。 – thelatemail

+0

感謝 - 再次一個真棒答案 - 尚未達到向量化代碼或應用()功能,但我知道他們。作爲您的答案的結果,我還了解了更多關於grep和grepl以及他們如何返回答案的信息 - 非常有幫助 – James