我有一个这样的数据框:
X <- data.frame(value = c(1,2,3,4),
variable = c("cost", "cost", "reed_cost", "reed_cost"))
我想将变量列分成两部分;一列表示变量是否为成本&#39;和另一列,以表明该变量是否是&#34; reed&#34;。我似乎无法找出合适的正则表达式(例如使用tidyr)
如果我的数据更好,请说:
Y <- data.frame(value = c(1,2,3,4),
variable = c("adjusted_cost", "adjusted_cost", "reed_cost", "reed_cost"))
然后这对tidyr来说是微不足道的:
separate(Y, variable, c("Type", "Model"), "_")
和宾果。相反,看起来我需要某种条件语句来分裂&#34; _&#34;如果它存在,否则在模式的开头分开(&#34; ^&#34;)。
我试过了:
separate(X, variable, c("Policy-cost", "Reed"), "(?(_)_|^)", perl=TRUE)
但没有运气。我意识到我甚至无法成功地拆分成空字符串:
separate(X, variable, c("Policy-cost", "Reed"), "^", perl=TRUE)
我应该怎么做?
编辑 注意这是一个较大问题的最小示例,其中有许多可能的变量(不只是cost
和{{1} })所以我不希望每个字符串匹配。
我正在寻找一种解决方案,如果存在,则按reed_cost
模式拆分任意变量,否则将它们拆分为空白字符串和原始标签。
我也意识到我可以只查看_
的存在,然后手动构建列。如果不那么优雅,这很好;似乎应该有一种方法可以使用可以返回空字符串的条件分割字符串...
答案 0 :(得分:1)
假设您可能有也可能没有分隔符,且费用和芦苇不一定互相排斥,为什么不搜索特定的字符串而不是分隔符呢?
示例:
library(stringr)
X <- data.frame(value = c(1,2,3,4),
variable = c("cost", "cost", "reed_cost", "reed_cost"))
X$cost <- str_detect(X$variable,"cost")
X$reed <- str_detect(X$variable,"reed")
答案 1 :(得分:1)
你可以尝试:
X$variable <- ifelse(!grepl("_", X$variable), paste0("_", X$variable), as.character(X$variable))
separate(X, variable, c("Policy-cost", "Reed"), "_")
# value Policy-cost Reed
#1 1 cost
#2 2 cost
#3 3 reed cost
#4 4 reed cost
或者
X$variable <- gsub("\\b(?=[A-Za-z]+\\b)", "_", X$variable, perl=T)
X$variable
#[1] "_cost" "_cost" "reed_cost" "reed_cost"
separate(X, variable, c("Policy-cost", "Reed"), "_")
\\b(?=[A-Za-z]+\\b)
:匹配单词边界\\b
并预览字符后跟字边界。第三和第四个元素不匹配,因此没有被替换。
答案 2 :(得分:1)
基础R的另一种方法:
cbind(X["value"],
setNames(as.data.frame(t(sapply(strsplit(as.character(X$variable), "_"),
function(x)
if (length(x) == 1) c("", x)
else x))),
c("Policy-cost", "Reed")))
# value Policy-cost Reed
# 1 1 cost
# 2 2 cost
# 3 3 reed cost
# 4 4 reed cost