1

我有一个包含句点的字符串列的data.frame,例如“abcX”。我想按句点拆分字符串并保留第三段,例如给出的示例中的“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
4

4 回答 4

2

问题不在于您的功能,within而在于您的get功能。它返回一个字符 ( "a"),当添加到您的 data.frame 时会被回收。您的代码应如下所示:

get.third <- function(x) sapply(strsplit(x, "\\."), `[[`, 3)
within(df, v <- get.third(as.character(v)))
于 2013-07-19T00:02:34.660 回答
2

这是一种可能的解决方案:

df[, "v"] <- do.call(rbind, strsplit(as.character(df[, "v"]), "\\."))[, 3]

## > df
##   v b
## 1 a 1
## 2 b 2
## 3 c 3
于 2013-07-19T00:03:25.683 回答
2

使用一些正则表达式,您可以:

gsub(".*?[.].*?[.](.*?)[.].*", '\\1', df$v)
[1] "a" "b" "c"

或者更简洁:

gsub("(.*?[.]){2}(.*?)[.].*", '\\2', v)
于 2013-07-19T01:02:33.570 回答
0

“我做错了什么”的答案是,您认为提取每个拆分字符串的第三个元素的代码实际上是将所有字符串的所有元素放在一个向量中,然后返回的第三个元素那:

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)))
于 2013-07-19T00:08:58.217 回答