使用数字变量进行分组

时间:2017-03-21 20:19:15

标签: r

我有一个像这样的数据框:

name, value
stockA,Google
stockA,Yahoo
stockB,NA
stockC,Google

我想将第二列的行值转换为列并保留第一列,而在另一列中将数值转换为0,如果不存在则为1或存在该值。这是预期输出的一个例子:

name,Google,Yahoo
stockA,1,1
stockB,0,0
stockC,1,0

我试过了:

library(reshape2)
df2 <- dcast(melt(df, 1:2, na.rm = TRUE), df + name ~ value, length)

它给我的错误是:

Using value as value column: use value.var to override.
Error in `[.data.frame`(x, i) : undefined columns selected

对错误有任何想法吗?

上一代码有效的示例。 数据(df):

name,nam2,value
stockA,sth1,Yahoo
stockA,sth2,NA
stockB,sth3,Google

这有效:

df2 <- dcast(melt(df, 1:2, na.rm = TRUE), name + nam2 ~ value, length)

4 个答案:

答案 0 :(得分:1)

您可以使用spread包中的tidyr执行此操作。

df <- data.frame(name = c("stockA", "stockA", "stockB", "stockC"),
                 value = c("Google", "Yahoo", NA, "Google"))
df$row <- 1
df %>% 
  spread(value, row, fill = 0) %>% 
  select(-`<NA>`)

答案 1 :(得分:1)

OP要求解释由

引起的错误
dcast(melt(df, 1:2, na.rm = TRUE), df + name ~ value, length)

(我很惊讶到目前为止还没有人试图改进OP的reshape2方法来准确回复预期的答案。)

OP的代码有几个问题:

    {li> df出现在dcast()公式中。
  1. melt()的第二个参数是1:2,这意味着所有列都用作id.vars。它应该是1
  2. 但最关键的一点是data.frame df已经是 long 格式,不需要重新整形。
  3. 因此,df可以直接用于dcast()

    library(reshape2)
    dcast(df[!is.na(df$value), ], name ~ value, length, drop = FALSE)
    #    name Google Yahoo
    #1 stockA      1     1
    #2 stockB      0     0
    #3 stockC      1     0
    

    为了避免在结果中出现第三个NA列,必须在重新整形前从NA过滤掉df行。另一方面,drop = FALSE需要确保stockB包含在结果中。

    数据

    df <- data.frame(name = c("stockA", "stockA", "stockB", "stockC"), 
                     value = c("Google", "Yahoo", NA, "Google"))
    df
    #    name  value
    #1 stockA Google
    #2 stockA  Yahoo
    #3 stockB   <NA>
    #4 stockC Google
    

答案 2 :(得分:0)

尝试df2 <- dcast(melt(df, 1:2, na.rm = TRUE), name ~ value, length)

只需从等式中删除df +

虽然这会给你一个额外的NA值列,这让我觉得na.rm参数在你的公式中没有正常工作。

答案 3 :(得分:0)

你也可以用基础R:

来做
df <- read.table(header=TRUE, sep=',', text=
'name, value
stockA,Google
stockA,Yahoo
stockB,NA
stockC,Google')
xtabs(~., data=df)
#        value
#name     Google Yahoo
#  stockA      1     1
#  stockB      0     0
#  stockC      1     0