如何正确操作R中数据框中的字符串列?

时间:2013-07-18 23:50:21

标签: regex r string dataframe

我有一个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

4 个答案:

答案 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)))