R - mutate for string processing - 没有得到我希望的行为

时间:2016-01-06 21:59:37

标签: r string dplyr

我正在尝试在dplyr中使用mutate来处理字符串而我没有得到我想要的输出(见下文),而不是逐行操作,mutate是第一个元素并向下填充它。我想知道是否有人可以帮助我理解我做错了什么以及如何调整这些代码以便正常工作。

short.idfun = function(longid) 
{
    x      = strsplit(longid,"_")
    y      = x[[1]]
    study  = substr(y[1],8,nchar(y[1]))
    subj   = y[length(y)]
    subj   = substr(subj,regexpr("[^0]",subj),nchar(subj)) #remove leading zeros
    shortid= paste(study,subj,sep="-")
    return(shortid)
}

data = data.frame(test=c("1234567Andy_003_003003","1234567Beth_004_003004","1234567Char_003_003005"),stringsAsFactors=FALSE)
data= mutate(data,shortid=short.idfun(test))
print(data)

#### Below is my output
#                       test   shortid
#1    1234567Andy_003_003003 Andy-3003
#2    1234567Beth_004_003004 Andy-3003
#3    1234567Char_003_003005 Andy-3003

#### This is the behavior I was hoping for
#                       test   shortid
#1    1234567Andy_003_003003 Andy-3003
#2    1234567Beth_004_003004 Beth-3004
#3    1234567Char_003_003005 Char-3005

2 个答案:

答案 0 :(得分:1)

另一种选择是使用rowwise()

data %>%
  rowwise() %>% 
  mutate(shortid = short.idfun(test))

给出了:

#Source: local data frame [3 x 2]
#Groups: <by row>
#
#                    test   shortid
#                   (chr)     (chr)
#1 1234567Andy_003_003003 Andy-3003
#2 1234567Beth_004_003004 Beth-3004
#3 1234567Char_003_003005 Char-3005

答案 1 :(得分:0)

问题是你的功能需要一些帮助矢量化。您可以通过vapply运行它来获取您之后的内容。

data = data.frame(test=c("1234567Andy_003_003003","1234567Beth_004_003004","1234567Char_003_003005"),stringsAsFactors=FALSE)
data= mutate(data,
             shortid=vapply(test, short.idfun, character(1)))
print(data)

要了解为什么你得到了你所做的结果,我们可以在你的功能的前几行看一点。

longid = data$test
(x <- strsplit(longid, "_"))
[[1]]
[1] "1234567Andy" "003"         "003003"     

[[2]]
[1] "1234567Beth" "004"         "003004"     

[[3]]
[1] "1234567Char" "003"         "003005" 

到目前为止,一切看起来都不错,但现在您定义了y

(y      = x[[1]])

[1] "1234567Andy" "003"         "003003" 

通过调用x[[1]],您只撤出了x的第一个元素,而不是x中的第一个元素,而不是x中每个向量的第一个元素。您还可以通过定义y <= vapply(x, function(v) v[1], character(1))并跳过vapply中的mutate来修改您的功能。无论哪种方式都应该有效。