7

私は次のデータ構造を持っています

ID  Type  Values
1   A     5; 7; 8
2   A     6
3   B     2; 3

そして、Rを使用して次のように変形したいと思います:

ID  Type  Values
1   A     5
1   A     7
1   A     8
2   A     6
3   B     2
3   B     3

私はplyrでそれを行う方法を考え出そうとしましたが、成功しませんでした. これを行う最善の方法は何ですか?

4

6 に答える 6

5

あなたが解決策を求めたのでplyr、ここに行きます:

ddply(df, .(Type), function(foo) {
    values <- unlist(strsplit(c(foo$Values), ";"))
    data.frame(Type = rep(unique(foo$Type), length(values)), Values = values)
    })
于 2012-10-01T13:29:41.780 に答える
5

data.tableエレガンスをコーディングするためのアプローチ

library(data.table)
DT <- data.table(dat)
DT[, list(Value = unlist(strsplit(as.character(Values), '; '))), by = list(ID, Type)]
于 2012-10-16T05:37:02.263 に答える
2

私のショット:

a <- data.frame(id = 1:3, 
                type = c("A", "A", "B"), 
                values = c("5; 7; 8", "6", "2; 3"))

g <- strsplit(as.character(a$values), ";")
data.frame(id = rep(a$id, lapply(g, length)), 
            type = rep(a$type, lapply(g, length)),
            values = unlist(g))
于 2012-10-01T13:42:30.633 に答える
1

美しい答えではありませんが、役に立つかもしれません

DF <- data.frame(ID=1:3,
                 Type=c('A','A','B'), 
                 Values=c(' 5; 7; 8', '6', ' 2;3')) # this is your df

    # split vectors and coercing values to be numeric
    List <- lapply(strsplit(Values, ';'), as.numeric)

# The desired output
    data.frame(ID=rep(ID, sapply(List, length)), 
               Type=rep(Type, sapply(List, length)),
               Values =   unlist(List))
 ID Type Values
1  1    A      5
2  1    A      7
3  1    A      8
4  2    A      6
5  3    B      2
6  3    B      3
于 2012-10-01T13:23:03.543 に答える
1

これまでの答えは素晴らしいです。ここにさらに別のものがあります。

# The data
DF <- data.frame(ID=1:3,
                 Type=c('A','A','B'), 
                 Values=c(' 5; 7; 8', '6', ' 2;3'))

このソリューションはcolsplit()、「reshape2」パッケージの関数を使用します。1 つの欠点は、必要な結果の列の数を知っていることを期待していることです。

require(reshape2)
DF2 <- data.frame(DF[-3], colsplit(DF$Values, ";", c("V.1", "V.2", "V.3")))
na.omit(melt(DF2, id.vars=c("ID", "Type")))
#   ID Type variable value
# 1  1    A      V.1     5
# 2  2    A      V.1     6
# 3  3    B      V.1     2
# 4  1    A      V.2     7
# 6  3    B      V.2     3
# 7  1    A      V.3     8

ここから、必要に応じて列をソートおよびドロップして、最終的な目的の出力を得ることができます。

于 2012-10-01T17:33:30.837 に答える
0

これはうまくいくはずですが、もっと良いアプローチがあるかもしれません:

#recreate data set
dat <- data.frame(ID=1:3, Type=c("A", "A", "B"), Values=c("5; 7; 8", "6", "2; 3"))
#split the Value column by ;
a <- strsplit(as.character(dat$Values), ";", fixed=TRUE)
#remove extra white
a <- lapply(a, function(x) gsub("^\\s+|\\s+$", "", x))
#get the length of each cell in Value so we can use this to index the rows
lens <- sapply(a, length)
#index rows and rename row names to numeric indexes
dat2 <- dat[rep(1:nrow(dat), lens), 1:2]
rownames(dat2) <- NULL
#add the stretched new column back
dat2$Value <- as.numeric(unlist(a))
于 2012-10-01T13:21:23.867 に答える