2017-10-17 110 views
0

我有一個很大的數據框。的較小子集如下:根據R中特定列名從字符向量中刪除逗號

structure(list(Date = c("2017-08-12", "2017-08-12", "2017-08-12" 
), `Time (sec)` = c("19:01:04", "07:30:18", "04:29:38"), `4+DURATION` = c("26", 
    "58,000", "27"), `4+'000 (AVG)` = c("0.0000", "0.0000", "0.0000"), 
    `15+DURATION` = c("26", "57,000", "27"), `15+'000 (AVG)` = c("0.0000", 
    "0.0000", "0.0000")), .Names = c("Date", "Time (sec)", "4+DURATION", 
    "4+'000 (AVG)", "15+DURATION", "15+'000 (AVG)"), row.names = 3:5, class = "data.frame") 

實際的數據幀看起來像這樣:

 Date Time (sec) 4+DURATION 4+'000 (AVG) 15+DURATION 15+'000 (AVG) 
3 2017-08-12 19:01:04   26  0.0000   26  0.0000 
4 2017-08-12 07:30:18  58,000  0.0000  57,000  0.0000 
5 2017-08-12 04:29:38   27  0.0000   27  0.0000 

在此從第3列以後的列的其餘部分存儲爲字符向量。我試圖將字符轉換爲數字。以下是我使用的代碼。

cols.num <- names(dat[,-c(1:2)]) 
dat[cols.num] <- sapply(dat[cols.num],as.numeric) 

dat是我的數據框。這會在兩個持續時間列中強制使用NA值,其中字符值中包含額外的逗號。

我試圖通過

df[,unique(grep("DUR", names(df), value=T))] <- gsub(",","",df[,unique(grep("DUR", names(df), value=T))]) 

刪除它但這創建這樣

Date Time (sec)   4+DURATION 4+'000 (AVG)   15+DURATION 15+'000 (AVG) 
3 2017-08-12 19:01:04 c("26" "58000" "27")  0.0000 c("26" "57000" "27")  0.0000 
4 2017-08-12 07:30:18 c("26" "57000" "27")  0.0000 c("26" "58000" "27")  0.0000 
5 2017-08-12 04:29:38 c("26" "58000" "27")  0.0000 c("26" "57000" "27")  0.0000 

但是所希望的輸出是一個DF:

Date Time (sec) 4+DURATION 4+'000 (AVG) 15+DURATION 15+'000 (AVG) 
3 2017-08-12 19:01:04   26  0.0000   26  0.0000 
4 2017-08-12 07:30:18  58000  0.0000  57000  0.0000 
5 2017-08-12 04:29:38   27  0.0000   27  0.0000 

在該數據幀中的問題是,我不知道哪一列將會有持續時間值,持續時間值的列名從4+開始持續變化DURATION到45 + DURATION等等。我想在將矢量提供給數字之前,用名字中的DURATION去除所有矢量中的逗號。

+2

您需要'應用'它。 'gsub'不是矢量化的。 df [,unique(grep(「DUR」,names(df),value = T))] - lapply(df [,unique(...))],function(i)gsub(...)) ' – Sotos

+0

@Sotos謝謝....知道了。我嘗試着申請......並進入了一個永無止境的麻煩拍攝......可以接受這個答案。 – Apricot

回答

2

你需要把它*apply感興趣的字段,因爲gsub(僅供參考,sub也會做就好了這裏)是量化,即

df[,unique(grep("DUR", names(df), value=T))] <- 
        lapply(df[,unique(grep("DUR", names(df), value=T))], function(i) 
                  as.numeric(sub(',', '', i))) 

其中給出,

 Date Time (sec) 4+DURATION 4+'000 (AVG) 15+DURATION 15+'000 (AVG) 
3 2017-08-12 19:01:04   26  0.0000   26  0.0000 
4 2017-08-12 07:30:18  58000  0.0000  57000  0.0000 
5 2017-08-12 04:29:38   27  0.0000   27  0.0000 
#str(df) 
#'data.frame': 3 obs. of 6 variables: 
# $ Date   : chr "2017-08-12" "2017-08-12" "2017-08-12" 
# $ Time (sec) : chr "19:01:04" "07:30:18" "04:29:38" 
# $ 4+DURATION : num 26 58000 27 
# $ 4+'000 (AVG) : chr "0.0000" "0.0000" "0.0000" 
# $ 15+DURATION : num 26 57000 27 
# $ 15+'000 (AVG): chr "0.0000" "0.0000" "0.0000" 
1

一個dplyr解決方案:

d <- structure(list(Date = c("2017-08-12", "2017-08-12", "2017-08-12" 
), `Time (sec)` = c("19:01:04", "07:30:18", "04:29:38"), `4+DURATION` = c("26", 
    "58,000", "27"), `4+'000 (AVG)` = c("0.0000", "0.0000", "0.0000"), 
    `15+DURATION` = c("26", "57,000", "27"), `15+'000 (AVG)` = c("0.0000", 
    "0.0000", "0.0000")), .Names = c("Date", "Time (sec)", "4+DURATION", 
    "4+'000 (AVG)", "15+DURATION", "15+'000 (AVG)"), row.names = 3:5, class = "data.frame") 
d2 <- d %>% mutate_at(vars(contains('DURATION')), funs(as.numeric(gsub(',', '', .)))) 
str(d2) 
+1

你也可以使用更多最近的'dplyr' pkg版本'mutate_at(vars(contains('DURATION')),〜as.numeric(gsub(',',',。)))' – hrbrmstr

+0

感謝你的建議! –