R等价于itertools.chain

时间:2014-02-13 23:46:54

标签: r reshape

我有一个如下所示的数据集:

   t   x   y
1  0   0   0
2  1  10   9
3  2  20  18
4  3  30  27
...

我想折叠将数据集的每一行垂直展开到一个新列z。目标看起来像这样:

   t   z
1  0   0
2  0   0
3  1  10
4  1   9
5  2  20
6  2  18
7  3  30
8  3  27
...

在Python中,我会将itertools.chain用于此目的:

import itertools

# Make some fake data
data = [{'t':t, 'x':t*10, 'y':t*9} for t in xrange(10)]
# [ {'t': 0, 'y':  0, 'x':  0},
#   {'t': 1, 'y':  9, 'x': 10},
#   {'t': 2, 'y': 18, 'x': 20},
# ...]

# transformation...
list(itertools.chain(*(({'t':x['t'], 'z':x['x']}, {'t':x['t'], 'z':x['y']})
                        for x in data)
     ))
# [{'z':  0, 't': 0},
#  {'z':  0, 't': 0},
#  {'z': 10, 't': 1},
#  {'z':  9, 't': 1},
#  {'z': 20, 't': 2},
#  {'z': 18, 't': 2},
# ...]

我使用 reshape 包进行了大量不同的尝试(meltt分组似乎非常接近我想要的,但按{{1}排序据我所知,这是不稳定的。

3 个答案:

答案 0 :(得分:1)

您可以使用例如

来实现此目的
dfx.temp <- df[,c(1,2)]
dfy.temp <- df[,c(1,2)]
names(dfx.temp) <- c("t","z")
names(dfy.temp) <- c("t","z")
df <- rbind(dfx.temp, dfy.temp)

添加df <- df[order(df$t),]以按照您要求的确切顺序获取。

答案 1 :(得分:1)

library(reshape2)
df2 <- melt(df, id.vars = "t")
df2
#   t variable value
# 1 0        x     0
# 2 1        x    10
# 3 2        x    20
# 4 3        x    30
# 5 0        y     0
# 6 1        y     9
# 7 2        y    18
# 8 3        y    27

可能订购行,并选择相关列。

df2[order(df2$t), c("t", "value")]
#   t value
# 1 0     0
# 5 0     0
# 2 1    10
# 6 1     9
# 3 2    20
# 7 2    18
# 4 3    30
# 8 3    27

答案 2 :(得分:1)

以下是另外两个选项......

melt类似,但在基础R中:

out <- cbind(t = mydf[, 1], stack(mydf[-1]))
out[order(out$t, out$ind), c("t", "values")]
#   t values
# 1 0      0
# 5 0      0
# 2 1     10
# 6 1      9
# 3 2     20
# 7 2     18
# 4 3     30
# 8 3     27

“data.table”方法:

library(data.table)
DT <- data.table(mydf)
DT[, unlist(.SD), by = "t"]
#    t V1
# 1: 0  0
# 2: 0  0
# 3: 1 10
# 4: 1  9
# 5: 2 20
# 6: 2 18
# 7: 3 30
# 8: 3 27

两个示例都使用以下内容作为“mydf”:

mydf <- data.frame(t = 0:3, x = seq(0, 30, 10), y = seq(0, 27, 9))