问题描述
我正在尝试使用mutate_at将flags列拆分为r中的多个新列,然后分离函数。我已经简化并清理了解决方案,如下所示,但是我收到一条错误消息,该错误表明整个数据列都被传递到了我的函数中,而不是单独传递给每一行。这是仅要求我遍历函数内部x的每个元素的正常行为吗?还是我不正确地调用mutate_at函数?
示例数据:
dataVariable <- data.frame(c_flags = c(".q.q.q","y..i.o","0x5a",".lll.."))
功能:
dataVariable <- read_csv("...",col_types = cols(
c_date = col_datetime(format = ""),c_dbl = col_double(),c_flags = col_character(),c_class = col_factor(c("a","b","c")),c_skip = col_skip()
))
funTranslateXForNewColumn <- function(x){
binary = ""
if(startsWith(x,"0x")){
binary=hex2bin(x)
} else {
binary = c(0,0)
splitFlag = strsplit(x,"")[[1]]
for(i in splitFlag){
flagVal = 1
if(i=="."){
flagVal = 0
}
binary=append(binary,flagVal)
}
}
return(paste(binary[4:12],collapse='' ))
}
mutate_at(dataVariable,vars(c_flags),funs(funTranslateXForNewColumn(.)))
separate(dataVariable,c_flags,c(NA,"flag_1","flag_2","flag_3","flag_4","flag_5","flag_6","flag_7","flag_8","flag_9"),sep="")
我收到的错误是:
Warning messages:
1: Problem with `mutate()` input `c_flags`.
i the condition has length > 1 and only the first element will be used
将字符串转换为标志的适当二进制表示形式之后,我将使用单独的函数将其拆分为新列。
解决方法
通过将mutate_at函数替换为:
dataVariable$binFlags <- mapply(funTranslateXForNewColumn,dataVariable$c_flags)
但是我想知道如何正确使用mutate_at函数。
信用至:https://datascience.stackexchange.com/questions/41964/mutate-with-custom-function-in-r-does-not-work
上面的链接还包括使该功能生效的解决方案,该功能是矢量化功能:
v_funTranslateXForNewColumn <- Vectorize(funTranslateXForNewColumn)
mutate_at(dataVariable,vars(c_flags),funs(v_funTranslateXForNewColumn(.)))
,
类似于OP的逻辑,但可能更短:
dataVariable$binFlags <- sapply(strsplit(dataVariable$c_flags,''),function(x)
paste(as.integer(x != '.'),collapse = ''))
如果您想使用dplyr
进行此操作,我们可以实现与以下相同的逻辑:
library(dplyr)
dataVariable %>%
mutate(binFlags = purrr::map_chr(strsplit(c_flags,~paste(as.integer(. != '.'),collapse = '')))
# c_flags binFlags
#1 .q.q.q 010101
#2 y..i.o 100101
#3 .lll.. 011100
mutate_at
/ across
用于要将功能应用于多个列的情况。而且,我在这里看不到您仅创建一个新的二进制列,而没有创建帖子中提到的多个新列。