ループを使用してこれを解決することもできますが、コードをよりR風にするために、ベクトルで考えるようにしています。
名前のリストがあります。形式はfirstname_lastnameです。このリストから、名だけを含む別のリストを取得したいと思います。どうすればいいのか気になっていないようです。以下にデータの例をいくつか示します。
t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
tsplit <- strsplit(t,"_")
これは次のようになります:
> tsplit
[[1]]
[1] "bob" "smith"
[[2]]
[1] "mary" "jane"
[[3]]
[1] "jose" "chung"
[[4]]
[1] "michael" "marx"
[[5]]
[1] "charlie" "ivan"
次のようなループを使用して、必要なものを取得できます。
for (i in 1:length(tsplit)){
if (i==1) {t_out <- tsplit[[i]][1]} else{t_out <- append(t_out, tsplit[[i]][1])}
}
これは私にこれを与えるでしょう:
t_out
[1] "bob" "mary" "jose" "michael" "charlie"
では、ループなしでこれを行うにはどうすればよいですか?
apply
(またはsapply
)を使用できます
t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
f <- function(s) strsplit(s, "_")[[1]][1]
sapply(t, f)
bob_smith mary_jane jose_chung michael_marx charlie_ivan
"bob" "mary" "jose" "michael" "charlie"
参照: Rの「適用」の簡単な紹介
そしてもう一つのアプローチ:
_t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
pieces <- strsplit(t,"_")
sapply(pieces, "[", 1)
_
つまり、最後の行はリストの各コンポーネントの最初の要素を抽出し、それをベクトルに簡略化します。
これはどのように作動しますか?まあ、あなたは_x[1]
_を書く別の方法が"["(x, 1)
であることを理解する必要があります。つまり、サブセット化を行う_[
_という関数があります。 sapply
呼び出しは、元のリストの要素ごとにこの関数を1回呼び出し、2つの引数(リスト要素と1)を渡します。
他の方法に対するこのアプローチの利点は、分割を再計算せずにリストから複数の要素を抽出できることです。たとえば、姓はsapply(pieces, "[", 2)
になります。このイディオムに慣れると、非常に読みやすくなります。
どうですか:
tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
fnames <- gsub("(_.*)$", "", tlist)
# _.* matches the underscore followed by a string of characters
# the $ anchors the search at the end of the input string
# so, underscore followed by a string of characters followed by the end of the input string
regExアプローチについては?
何について:
t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
sub("_.*", "", t)
これが最もエレガントな解決策ではないかと思いますが、ループ処理に勝っています。
t.df <- data.frame(tsplit)
t.df[1, ]
リストをデータフレームに変換することは、リストを自分のやりたいことを実行させる唯一の方法です。リストの扱い方を実際に理解されている方の回答を楽しみにしています。
あなたはそれをほとんど持っていました。それ本当にはただの問題です
*apply
_関数の1つを使用して既存のリストをループします。私はlapply
で始まることが多く、場合によってはsapply
に切り替えますstrsplit(string, splitterm)
であることをすでに知っていて、答えの最初の項を選ぶには奇妙な_[[1]][1]
_が必要であることを知っていますt
またはc
とその仲間たちから離れているため)から始めて、すべてをまとめます。与える
_> tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
> fnames <- sapply(tlist, function(x) strsplit(x, "_")[[1]][1])
> fnames
bob_smith mary_jane jose_chung michael_marx charlie_ivan
"bob" "mary" "jose" "michael" "charlie"
>
_
unlist()
を使用できます:
> tsplit <- unlist(strsplit(t,"_"))
> tsplit
[1] "bob" "smith" "mary" "jane" "jose" "chung" "michael"
[8] "marx" "charlie" "ivan"
> t_out <- tsplit[seq(1, length(tsplit), by = 2)]
> t_out
[1] "bob" "mary" "jose" "michael" "charlie"
奇数インデックスのエントリのみを取得するより良い方法があるかもしれませんが、いずれにしてもループはありません。
そして、ブレントンクの非公開の例に基づくもう1つのアプローチ...
tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
tsplit <- unlist(strsplit(tlist,"_"))
fnames <- tsplit[seq(1:length(tsplit))%%2 == 1]
次のunlist()ベースのメソッドを使用します。
> t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
> tsplit <- strsplit(t,"_")
>
> x <- matrix(unlist(tsplit), 2)
> x[1,]
[1] "bob" "mary" "jose" "michael" "charlie"
この方法の大きな利点は、姓の同等の問題を同時に解決できることです。
> x[2,]
[1] "smith" "jane" "chung" "marx" "ivan"
欠点は、すべての名前がfirstname_lastname
構造に準拠していることを確認する必要があることです。もしそうでなければ、このメソッドは壊れます。
最初に与えられた元のtsplit
リストオブジェクトから、このコマンドは次のことを行います。
unlist(lapply(tsplit,function(x) x[1]))
すべてのリスト要素の最初の要素を抽出してから、リストをベクトルに変換します。最初にマトリックスへのリストを解除してから最初の列を抽出することもできますが、すべてのリスト要素が同じ長さであるという事実に依存しています。出力は次のとおりです。
> tsplit
[[1]]
[1] "bob" "smith"
[[2]]
[1] "mary" "jane"
[[3]]
[1] "jose" "chung"
[[4]]
[1] "michael" "marx"
[[5]]
[1] "charlie" "ivan"
> lapply(tsplit,function(x) x[1])
[[1]]
[1] "bob"
[[2]]
[1] "mary"
[[3]]
[1] "jose"
[[4]]
[1] "michael"
[[5]]
[1] "charlie"
> unlist(lapply(tsplit,function(x) x[1]))
[1] "bob" "mary" "jose" "michael" "charlie"