R plyr,data.table,应用data.frame的某些列

Bra*_*rad 5 r apply plyr data.table

我正在寻找加速我的代码的方法.我正在调查apply/ ply方法以及data.table.不幸的是,我遇到了问题.

这是一个样本数据:

ids1   <- c(1, 1, 1, 1, 2, 2, 2, 2)
ids2   <- c(1, 2, 3, 4, 1, 2, 3, 4)
chars1 <- c("aa", " bb ", "__cc__", "dd  ", "__ee", NA,NA, "n/a")
chars2 <- c("vv", "_ ww_", "  xx  ", "yy__", "  zz", NA, "n/a", "n/a")
data   <- data.frame(col1 = ids1, col2 = ids2, 
                 col3 = chars1, col4 = chars2, 
          stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)

这是一个使用循环的解决方案:

library("plyr")
cols_to_fix <- c("col3","col4")
for (i in 1:length(cols_to_fix)) {
  data[,cols_to_fix[i]] <- gsub("_", "", data[,cols_to_fix[i]])
  data[,cols_to_fix[i]] <- gsub(" ", "", data[,cols_to_fix[i]])
  data[,cols_to_fix[i]] <- ifelse(data[,cols_to_fix[i]]=="n/a", NA, data[,cols_to_fix[i]])
} 
Run Code Online (Sandbox Code Playgroud)

我最初看过ddply,但我想使用的一些方法只采用向量.因此,我无法弄清楚如何ddply一个一个地跨越某些列.

此外,我一直在看laply,但我想返回原始data.frame的变化.谁能帮我?谢谢.


基于前面的建议,这是我试图从plyr包中使用的.

选项1:

data[,cols_to_fix] <- aaply(data[,cols_to_fix],2, function(x){
   x <- gsub("_", "", x,perl=TRUE)
   x <- gsub(" ", "", x,perl=TRUE)
   x <- ifelse(x=="n/a", NA, x)
},.progress = "text",.drop = FALSE)
Run Code Online (Sandbox Code Playgroud)

选项2:

data[,cols_to_fix] <- alply(data[,cols_to_fix],2, function(x){
   x <- gsub("_", "", x,perl=TRUE)
   x <- gsub(" ", "", x,perl=TRUE)
   x <- ifelse(x=="n/a", NA, x)
},.progress = "text")
Run Code Online (Sandbox Code Playgroud)

选项3:

data[,cols_to_fix] <- adply(data[,cols_to_fix],2, function(x){
   x <- gsub("_", "", x,perl=TRUE)
   x <- gsub(" ", "", x,perl=TRUE)
   x <- ifelse(x=="n/a", NA, x)
},.progress = "text")
Run Code Online (Sandbox Code Playgroud)

这些都没有给我正确的答案.

apply效果很好,但我的数据非常大,plyr包中的进度条非常好.再次感谢.

Aru*_*run 10

这是一个data.table使用的解决方案set.

require(data.table)
DT <- data.table(data)
for (j in cols_to_fix) {
    set(DT, i=NULL, j=j, value=gsub("[ _]", "", DT[[j]], perl=TRUE))
    set(DT, i=which(DT[[j]] == "n/a"), j=j, value=NA_character_)
}

DT
#    col1 col2 col3 col4
# 1:    1    1   aa   vv
# 2:    1    2   bb   ww
# 3:    1    3   cc   xx
# 4:    1    4   dd   yy
# 5:    2    1   ee   zz
# 6:    2    2   NA   NA
# 7:    2    3   NA   NA
# 8:    2    4   NA   NA
Run Code Online (Sandbox Code Playgroud)

第一行读取:在DT中为所有i(= NULL)设置,列= j为值gsub(..).
第二行读取:在DT中设置i(= condn),列= j,值为NA_character_.

注意:使用PCRE(perl=TRUE)具有很好的加速,特别是在较大的向量上.


mar*_*bel 7

这是一个data.table解决方案,如果你的桌子很大,应该更快.以下概念:=是列的"更新".我相信因为这个原因你不会再次在内部复制表,因为"正常"的数据帧解决方案会.

require(data.table)
DT <- data.table(data)

fxn = function(col) {
  col = gsub("[ _]", "", col, perl = TRUE)
  col[which(col == "n/a")] <- NA_character_
  col
}

cols = c("col3", "col4");

# lapply your function
DT[, (cols) := lapply(.SD, fxn), .SDcols = cols]
print(DT)
Run Code Online (Sandbox Code Playgroud)

  • +1也结帐`?set`.它避免了`[.data.table`开销,因此速度更快.特别适用于循环遍历每个列并更新值(通过引用). (2认同)