如何拆分data.frame - >将合并应用于子集 - >合并到data.frame

时间:2016-03-19 08:52:14

标签: r

如果不使用for循环,我真的不知道如何实现这一目标:

x <- c('a', 'b', 'c', 'd')

> x
[1] "a" "b" "c" "d"

data <- data.frame(
   x=c('a', 'b', 'a', 'b', 'c', 'a', 'a', 'b', 'c', 'd'),
   name=c('one','one', 'two','two','two', 'three', 'four','four','four','four'),
   other=c(1, 4, 5, 3, 2, 4, 5, 6, 3, 2)
)

> data
   x  name other
1  a   one     1
2  b   one     4
3  a   two     5
4  b   two     3
5  c   two     2
6  a three     4
7  a  four     5
8  b  four     6
9  c  four     3
10 d  four     2

我想将data除以namemerge每个子组x的值,以填充&#34;缺少的行&#34;,获取像这样的东西:

> data
   x  name other
1  a   one     1
2  b   one     4
   c   one     0 <- missing row added
   d   one     0 <- missing row added
3  a   two     5
4  b   two     3
5  c   two     2
   d   two     0 <- missing row added
6  a three     4
   b three     0 <- missing row added
   c three     0 <- missing row added
   d three     0 <- missing row added
7  a  four     5
8  b  four     6
9  c  four     3
10 d  four     2

最后,像这样重新格式化data.frame

> data
   x  one  two  three  four
1  a    1    5      4     5
2  b    4    3      0     6
3  c    0    2      0     3
4  d    0    0      0     2

我可以使用for循环来实现它,但我确信必须有一个更好的解决方案*applybysplit或类似的东西。有什么建议吗?

**更新**

我最后对接受的答案稍作修改(再次,tnx,伙计!),因为我不喜欢与levels合作,我不在乎列的顺序:

grid <- expand.grid(x, unique(data$name))
colnames(grid) <- c("x", "name")
data <- merge(grid, data, all.x = TRUE)
data[is.na(data)] <- 0
dcast(data, x ~ name, value.var = 'other')

3 个答案:

答案 0 :(得分:2)

试试xtabs。不需要包裹。

首先按顺序放置name的级别,以便列出来排序:

data$name <- factor(data$name, levels = c("one", "two", "three", "four"))
tab <- xtabs(other ~., data)

给出c("xtabs", "table")类输出:

> tab
   name
x   one two three four
  a   1   5     4    5
  b   4   3     0    6
  c   0   2     0    3
  d   0   0     0    2
如果需要输出as.data.frame.matrix(tab)类,请

或使用"data.frame"

答案 1 :(得分:1)

更直接:

你真正需要的只是reshape2::dcast

# clean up factor levels for prettier results
data$name <- factor(data$name, levels = c('one', 'two', 'three', 'four'))

library(reshape2)
dcast(data, x ~ name, value.var = 'other', fill = 0)

#   x one two three four
# 1 a   1   5     4    5
# 2 b   4   3     0    6
# 3 c   0   2     0    3
# 4 d   0   0     0    2

按要求:

要按照您列出的步骤操作,请先使用expand.grid获取组合,然后使用merge all = TRUE,然后使用reshape2::dcast重新排列:

df <- merge(data, expand.grid(x, levels(data$name)), 
            by.x = c('x', 'name'), by.y = c('Var1', 'Var2'), all = TRUE)

df[is.na(df)] <- 0         # replace `NA`s with 0
df$name <- factor(df$name, levels = c('one', 'two', 'three', 'four')) # fix order of levels

library(reshape2)
dcast(df, x ~ name, value.var = 'other')

#    x one two three four
# 1 a   1   5     4    5
# 2 b   4   3     0    6
# 3 c   0   2     0    3
# 4 d   0   0     0    2

答案 2 :(得分:0)

要回答您的第一部分,您可以使用expand.grid。这里应用的逻辑是:
您的数据:

x=c('a', 'b', 'a', 'b', 'c', 'a', 'a', 'b', 'c', 'd')
name=c('one','one', 'two','two','two', 'three', 'four','four','four','four')
other=c(1, 4, 5, 3, 2, 4, 5, 6, 3, 2)

将此设为数据框:

ee<-data.frame(x,name,other)

现在使用expand.grid展开并将所有组合应用于x和name:

dd<-expand.grid(unique(x), unique(name))

这看起来像:

    Var1  Var2
1     a   one
2     b   one
3     c   one
4     d   one
5     a   two
6     b   two
7     c   two
8     d   two
9     a three
10    b three
11    c three
12    d three
13    a  four
14    b  four
15    c  four
16    d  four

您已创建所有组合:现在使用SQLDF或任何合并包:

ff<-sqldf("select Var1, Var2, ifnull(c.other,0) from dd left join ee c on x=Var1 and name=Var2")

因此您的输出是:

    Var1  Var2 other
1     a   one     1
2     b   one     4
3     c   one     0
4     d   one     0
5     a   two     5
6     b   two     3
7     c   two     2
8     d   two     0
9     a three     4
10    b three     0
11    c three     0
12    d three     0
13    a  four     5
14    b  four     6
15    c  four     3
16    d  four     2
>