我有一个像这样的数据框:
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)
答案 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的代码有几个问题:
df
出现在dcast()
公式中。
melt()
的第二个参数是1:2
,这意味着所有列都用作id.vars
。它应该是1
。 df
已经是 long 格式,不需要重新整形。 因此,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