我有一个data.frame,其字符串列包含句点,例如“a.b.c.X”。我希望按句点拆分字符串并保留第三段,例如给出的例子中的“c”。这就是我正在做的事情。
> df = data.frame(v=c("a.b.a.X", "a.b.b.X", "a.b.c.X"), b=seq(1,3))
> df
v b
1 a.b.a.X 1
2 a.b.b.X 2
3 a.b.c.X 3
我想要的是
> df = data.frame(v=c("a.b.a.X", "a.b.b.X", "a.b.c.X"), b=seq(1,3))
> df
v b
1 a 1
2 b 2
3 c 3
我正在尝试使用within
,但我的结果很奇怪。第一列中第一行的值正在重复。
> get = function(x) { unlist(strsplit(x, "\\."))[3] }
> within(df, v <- get(as.character(v)))
v b
1 a 1
2 a 2
3 a 3
这样做的最佳做法是什么?我做错了什么?
更新: 这是我从@ agstudy的回答中使用的解决方案:
> df = data.frame(v=c("a.b.a.X", "a.b.b.X", "a.b.c.X"), b=seq(1,3))
> get = function(x) gsub(".*?[.].*?[.](.*?)[.].*", '\\1', x)
> within(df, v <- get(v))
v b
1 a 1
2 b 2
3 c 3
答案 0 :(得分:2)
问题不在于within
,而在于get
功能。它返回一个字符("a"
),在添加到data.frame时会被回收。您的代码应如下所示:
get.third <- function(x) sapply(strsplit(x, "\\."), `[[`, 3)
within(df, v <- get.third(as.character(v)))
答案 1 :(得分:2)
以下是一种可能的解决方案:
df[, "v"] <- do.call(rbind, strsplit(as.character(df[, "v"]), "\\."))[, 3]
## > df
## v b
## 1 a 1
## 2 b 2
## 3 c 3
答案 2 :(得分:2)
使用一些正则表达式,你可以这样做:
gsub(".*?[.].*?[.](.*?)[.].*", '\\1', df$v)
[1] "a" "b" "c"
或者更简洁:
gsub("(.*?[.]){2}(.*?)[.].*", '\\2', v)
答案 3 :(得分:0)
“我做错了什么”的答案是,您认为提取每个拆分字符串的第三个元素的代码实际上是将所有 所有的元素放在 all < / em>你的字符串在一个向量中,然后返回第三个元素:
get = function(x) {
splits = strsplit(x, "\\.")
print("All the elements: ")
print(unlist(splits))
print("The third element:")
print(unlist(splits)[3])
# What you actually wanted:
third_chars = sapply(splits, function (x) x[3])
}
within(df, v2 <- get(as.character(v)))