布尔转换的许多列中的因素

时间:2017-12-20 15:06:04

标签: r

我的问题有点像this,但数据结构的问题却有所不同:

示例数据:

df  <-data.frame(id = c(1,2,3), stock_1 = c("Google","Microsoft","Yahoo"), stock_2 = c("Yahoo","Google","NA"))

我想转换成这个:

df  <-data.frame(id = c(1,2,3), Google = c(1,1,0), Microsoft = c(0,1,0), Yahoo= c(1,0,1))

我尝试使用sapply(),但从链接问题的答案来看,它只适用于一列。

2 个答案:

答案 0 :(得分:5)

以下是使用data.table

执行此操作的方法
library(data.table)
setDT(df)
dcast(melt(df, id = 'id')[value != 'NA'],
      id ~ value, fun.aggregate = length)
#    id Google Microsoft Yahoo
# 1:  1      1         0     1
# 2:  2      1         1     0
# 3:  3      0         0     1

fill = 0是不必要的,为了容忍重复,我们可以尝试:

dcast(melt(df, id = 'id')[value != 'NA'],
      id ~ value, fun.aggregate = function(x){ 1 * (length(x) != 0)})
2017年1月1日

正如Uwe所说,我们可以通过设置NAna.rm = TRUE中删除它,如果它不是硬编码为字符串("NA"),命令最终会看起来这样:

dcast(melt(df, id = 'id', na.rm = TRUE), id ~ value, fun.aggregate = length)
# or
dcast(melt(df, id = 'id', na.rm = TRUE),
      id ~ value, fun.aggregate = function(x){ 1 * (length(x) != 0)})

答案 1 :(得分:2)

我们也可以使用tidyverse

执行此操作
library(tidyverse)
df %>%
   gather(key, val, -id) %>% 
   filter(!is.na(val)) %>% 
   mutate(ind = 1)  %>%
   select(-key) %>% 
   spread(val, ind, fill = 0)

注意:最好使用NA代替"NA",因为我们可以使用is.nana.omitcomplete.cases