5

私は、回答者が「どの種類の果物が好きですか?」という質問に答えるために 0 個以上の選択肢を選択できる一連の調査回答を持っています。書き込み回答欄もありました。結果のスプレッドシートでは、各人の回答が 1 つのセルに表示され、次のようにさまざまな種類の果物がカンマで区切られています。

(df <- data.frame(id = c("A", "B", "C", "D", "E"), 
                 data = c("oranges, apples, peaches, cherries, pineapples, strawberries",
                          "oranges, peaches, pears", 
                          "pears, nectarines, cherries (bing, rainier)", 
                          "apples, peaches, nectarines", 
                          ""), 
                 stringsAsFactors = FALSE))

#   id                                                         data
# 1  A oranges, apples, peaches, cherries, pineapples, strawberries
# 2  B                                      oranges, peaches, pears
# 3  C                  pears, nectarines, cherries (bing, rainier)
# 4  D                                  apples, peaches, nectarines
# 5  E  

私がやりたいことは、応答を長い形式の表に分割することです。これは、下部のコードを使用してほぼ達成できました。ただし、一部の回答者は書き込み応答にコンマを含めており、コンマで回答を分割したくありません. 元の複数選択オプションがすべて何であったかは知っています。これらの回答のみを分割して、書き込み (コンマ付き) をそのまま残すにはどうすればよいですか? 私はこのようなデータフレームで終わりたいです:

   id                               data
1   A                            oranges
2   A                             apples
3   A                            peaches
4   A cherries, pineapples, strawberries
5   B                            oranges
6   B                            peaches
7   B                              pears
8   C                              pears
9   C                         nectarines
10  C           cherries (bing, rainier)
11  D                             apples
12  D                            peaches
13  D                         nectarines

複数選択オプションは次のとおりです。

mc_answers <- c("oranges", "plums", "apples", "peaches", "pears", "nectarines")

私がこれまでに達成したことは次のとおりです。

# use strsplit to create a list of the types of fruit each person likes
datalist <- strsplit(df$data, ", ")
names(datalist) <- df$id

# remove zero-length list elements (person E doesn't like any fruit)
datalist <- Filter(length, datalist)

# convert list elements to data frames
datalist_dfs <- lapply(datalist, data.frame, stringsAsFactors = FALSE)
datalist_dfs <- lapply(datalist_dfs, setNames, "data") # name each column 'data'

# add id column to each data frame
data_long <- mapply(function(x, y) "[<-"(x, "id", value = y), datalist_dfs, 
                    names(datalist_dfs), SIMPLIFY = FALSE)

# combine into one big data frame
(data_per_person <- do.call('rbind', data_long))
#               data id
# A.1        oranges  A
# A.2         apples  A
# A.3        peaches  A
# A.4       cherries  A   # should
# A.5     pineapples  A   # be one
# A.6   strawberries  A   # entry
# B.1        oranges  B
# B.2        peaches  B
# B.3          pears  B
# C.1          pears  C
# C.2     nectarines  C
# C.3 cherries (bing  C   # should be 
# C.4       rainier)  C   # one entry
# D.1         apples  D
# D.2        peaches  D
# D.3     nectarines  D

人が何個の果物を選択できたかについてのルールはありませんが、書き込みの回答がある場合は、常に最後になります。

4

3 に答える 3

3

あなたも試すことができます:

 library(data.table)
 library(devtools)
 source_gist(11380733) ## 

 df1 <- cSplit(df, "data", sep=", ", "long")
 indx <- df1$data %in% mc_answers
 res <- rbindlist(list(df1[indx,], df1[!indx,][, list(data=paste(data, collapse=", ")), by=id]))[order(id)]

  res
  #   id                               data
  #1:  A                            oranges
  #2:  A                             apples
  #3:  A                            peaches
  #4:  A cherries, pineapples, strawberries
  #5:  B                            oranges
  #6:  B                            peaches
  #7:  B                              pears
  #8:  C                              pears
  #9:  C                         nectarines
 #10:  C           cherries (bing, rainier)
 #11:  D                             apples
 #12:  D                            peaches
 #13:  D                         nectarines
于 2014-08-03T08:20:32.013 に答える
2

このようなものはどうですか

do.call(rbind, lapply(split(df, df$id), function(x) {
    v<-unlist(strsplit(x$data, ",\\s?"))
    v<-c(v[v %in% mc_answers], paste(v[!v %in% mc_answers], collapse=", "))
    v<-v[nchar(v)>0]
    if (length(v)>0) {
        data.frame(id=x$id[1], data=v)
    } else {
        NULL
    }
}))

ここでは、分割して各グループを個別に処理してから、文字列分割を行います。mc_answers次に、ベクトルに含まれていないすべてのエントリを折りたたみます。戻る

    id                               data
A.1  A                            oranges
A.2  A                             apples
A.3  A                            peaches
A.4  A cherries, pineapples, strawberries
B.1  B                            oranges
B.2  B                            peaches
B.3  B                              pears
C.1  C                              pears
C.2  C                         nectarines
C.3  C           cherries (bing, rainier)
D.1  D                             apples
D.2  D                            peaches
D.3  D                         nectarines
于 2014-08-02T19:16:02.067 に答える