R
1> DT 2 id comment 31: 1 mary,hello,hoge 42: 2 bob,world
このようなデータフレームを、以下のように変形したいです。
なおcommentの中は文字列のリスト(c("mary","hello","hoge"))になっています。
R
1> DT 2 id comment 31: 1 mary 42: 1 hello 53: 1 hoge 62: 2 bob 72: 2 world
最悪for文を回せばできるのですが、tidyrのgatherのような感じで効率的に出来る方法があれば、是非ご教授願いたいです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
comment列を一気にばらす方法です
具体的には入れ子状とみて、nest化→map関数で","のところで分割→元に戻す方法です。遠回りです。
分割のときにちょうどいい列数を組めたら楽になるかもしれません。
R
1library(tidyverse) 2 3DT %>% 4 #comment列を入れ子にする 5 tidyr::nest(-id) %>% 6 #入れ子の2行に対してseparate関数で列を分割する 7 dplyr::mutate(model = dplyr::map(data, ~ separate(., col = comment, into = c("a", "b", "c"), sep = ","))) %>% 8 #入れ子を解除する。comment列が分割された状態で出てくる 9 tidyr::unnest() %>% 10 dplyr::select(-comment) %>% 11 tidyr::gather(key, value, -id) %>% 12 dplyr::filter(!is.na(value))
投稿2019/09/10 08:49
総合スコア15
0
少し長いですが、tidyverse でやるならこんな感じだと思います。
(もう少し上手くやる方法はあると思いますが)
R
1# データの作成 2df <- tibble(id = c(1, 2), 3 comment = c("mary,hello,hoge", "bob,world")) 4 5# 分割後のコメントがいくつ必要かを計算するために、各行の","の数を計算 6df <- df %>% 7 mutate(count = str_count(comment, ",")) 8 9# 分割後の最大コメント数を計算 10max_col <- (df$count %>% max()) + 1 11 12df %>% 13 # count はもう使わないので捨てる 14 select(-count) %>% 15 # comment を "," で分ける 16 separate(comment, 17 # 分けた先の列名を指定 18 into = str_c("col", 1:max_col), 19 sep = ",") %>% 20 # gather で縦長に変換 21 gather(key = col, value = comment, -id) %>% 22 # col がいらないので捨てる 23 select(-col) %>% 24 # NA が混ざっているので除去する 25 filter(!is.na(comment)) %>% 26 # 並び替える 27 arrange(id, comment)
R
1tibble: 5 x 2 2 id comment 3 <dbl> <chr> 41 1 hello 52 1 hoge 63 1 mary 74 2 bob 85 2 world
投稿2018/04/29 10:41
総合スコア73
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
効率的かどうかはさておき、形だけ合っていれば良いのなら以下のような感じでどうでしょう。
R
1# 処理前 2> DT 3 id comment 41 1 mary, hello, hoge 52 2 bob, world 6> str(DT) 7'data.frame': 2 obs. of 2 variables: 8 $ id : int 1 2 9 $ comment:List of 2 10 ..$ : chr "mary" "hello" "hoge" 11 ..$ : chr "bob" "world" 12 13 14library(reshape2) 15DT2 <- melt(DT$comment) 16names(DT2) <- c("comment", "id") 17DT2 <- DT2[,c(2,1)] 18DT2$comment <- as.character(DT2$comment) 19 20 21# 処理後 22> DT2 23 id comment 241 1 mary 252 1 hello 263 1 hoge 274 2 bob 285 2 world 29> str(DT2) 30'data.frame': 5 obs. of 2 variables: 31 $ id : int 1 1 1 2 2 32 $ comment: chr "mary" "hello" "hoge" "bob" ...
投稿2018/03/25 01:29
総合スコア1192
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
これでどうでしょう。なお「commentの中は文字列のリスト(c("mary","hello","hoge"))」とのことですが、そのようなdata.frameは作れないと思うので、単純にコンマ区切りの文字列であると仮定しています。
R
1df1 <- read.table( 2 text=" 3 id comment 4 1 mary,hello,hoge 5 2 bob,world 6 ", 7 header=T, 8 stringsAsFactors = F 9) 10 11l <- strsplit(df1$comment, ",") 12df2 <- data.frame( 13 id = rep(df1$id, sapply(l, length)), 14 comment= unlist(l) 15) 16 17print(df1) 18print(df2)
投稿2018/03/24 18:26
総合スコア13671
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。