【问题标题】:Data restructure in R (short lists to binary)R中的数据重组(二进制短列表)
【发布时间】:2014-05-30 13:27:15
【问题描述】:

我有一个具有这种结构的数据集:

区域1 区域2 区域3 1 10 5 5 2 8 10 8 3 13 15 12 4 3 17 11 5 17 9 6 12 15 7 4 8 18 9 1

我需要:

项目 区域1 区域2 区域3 1 1 1 0 0 2 3 1 0 0 3 4 1 0 0 4 5 0 1 1 5 8 1 0 1 6 9 0 0 1 7 10 1 1 0 8 11 0 0 1 9 12 1 0 1 10 13 1 0 0 11 15 0 1 1 12 17 1 1 0 13 18 1 0 0

计划是获得一个不同的项目列表,将每个区域作为自己的列连接,并将匹配项替换为 1,缺少的替换为 0;但我一定错过了 R 合并的一个关键点,删除了感兴趣的主列。任何意见是极大的赞赏!我更喜欢 R 解决方案,但下一步是研究 sqldf 包。

#read in data
regions <- read.csv("c:/data/regions.csv")

#get unique list of items from all regions
items <- na.omit(unique(stack(regions)[1]))

#merge distinct items with each region, replace matches with 1, missings with 0
merge.test <- merge(items,regions,by.x="values", by.y=c("region1"), all=TRUE)

【问题讨论】:

  • 能否提供dput的数据?

标签: r reshape data-manipulation


【解决方案1】:

帮助提供一个可重现的示例(即给我们一个简单的复制粘贴命令来构建您的示例数据)。

你没有说,所以我猜你的数据可能在一个列表中?

dat <- list(region1=c(10, 8, 3, 17, 12, 4, 18, 1),
            region2=c(5,10,15,17),
            region3=c(5,8,12,11,9,15))

首先找到所有的项目(可能不需要排序,我只是因为你的排序)

ids <- sort(unique(unlist(dat)))

然后对于每个区域,只需查看唯一 ID 列表是否在该区域中,将逻辑 TRUE/FALSE 强制为 0 和 1(如果对您有用,您可以保留为 T/F)

data.frame(ids,
    region1=as.integer(ids %in% dat$region1),
    region2=as.integer(ids %in% dat$region2),
    region3=as.integer(ids %in% dat$region3))

如果您只有 3 个区域就可以了,如果您有更多区域,您可能希望自动输入:

cols <- lapply(dat, function (region) as.integer(ids %in% region))
cols$id <- ids
df <- do.call(data.frame, cols)

do.call 使用列表 cols 作为其(命名)参数调用 data.frame 函数,即它只是这样做

data.frame(id=..., region1=..., region2=..., region3=...)

如果您的原始 dat 是 CSV 并且每列都有 NA 值,您可能需要根据需要插入 na.omit

【讨论】:

    【解决方案2】:

    使用@mathematical.coffee 的例子和qdap

    dat <- list(region1=c(10, 8, 3, 17, 12, 4, 18, 1),
                region2=c(5,10,15,17),
                region3=c(5,8,12,11,9,15))
    
    library(qdap)
    matrix2df(t(mtabulate(dat)), "item")
    

    您可能需要扩展:

    FUN <- function(x) as.numeric(x > 0)
    matrix2df(apply(t(mtabulate(dat)), 2, FUN), "item")
    

    如果向量中有多个项目。

    【讨论】:

      【解决方案3】:

      现有的答案很好,但它们似乎很复杂。试试stack + table吧:

      table(stack(dat))
      #       ind
      # values region1 region2 region3
      #     1        1       0       0
      #     3        1       0       0
      #     4        1       0       0
      #     5        0       1       1
      #     8        1       0       1
      #     9        0       0       1
      #     10       1       1       0
      #     11       0       0       1
      #     12       1       0       1
      #     15       0       1       1
      #     17       1       1       0
      #     18       1       0       0
      

      我还要冒昧地说,考虑到你目前的方法,你实际上有一个data.frame 而不是list

      DAT <- dat
      Len <- max(sapply(DAT, length))
      DAT <- data.frame(lapply(DAT, function(x) { length(x) <- Len; x }))
      

      在这种情况下,解决方案也不例外:

      table(stack(DAT))
      #       ind
      # values region1 region2 region3
      #     1        1       0       0
      #     3        1       0       0
      #     4        1       0       0
      #     5        0       1       1
      #     8        1       0       1
      #     9        0       0       1
      #     10       1       1       0
      #     11       0       0       1
      #     12       1       0       1
      #     15       0       1       1
      #     17       1       1       0
      #     18       1       0       0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多