1

「abcX」などのピリオドを含む文字列列を持つ data.frame があります。文字列をピリオドで分割し、3 番目のセグメント (例では "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

考えられる解決策の 1 つを次に示します。

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 に答える
2

問題は機能ではなくwithinget機能にあります。"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 に答える
0

「何が間違っているのか」に対する答えは、分割された各文字列の 3 番目の要素を抽出していると思っていたコードのビットが、実際にはすべての文字列のすべての要素を 1 つのベクトルに入れ3番目の要素を返していたことです。それ:

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 に答える