当前位置: 首页 > 知识库问答 >
问题:

R: 将数据分成两列的组合

胡墨竹
2023-03-14

我有一些数据,其中每个id由不同的类型测量,这些类型可以有不同的值。测量值为val。一个小的虚拟数据如下所示:

df <- data.frame(id=rep(letters[1:2],6), 
             type=c(rep('t1',6), rep('t2',6)),
             type_val=rep(c(1,1,2,2,3,3),2),
             val=1:12)

那么df是:

    id  type    type_val    val
1   a   t1  1   1
2   b   t1  1   2
3   a   t1  2   3
4   b   t1  2   4
5   a   t1  3   5
6   b   t1  3   6
7   a   t2  1   7
8   b   t2  1   8
9   a   t2  2   9
10  b   t2  2   10
11  a   t2  3   11
12  b   t2  3   12

我需要传播/投射数据,以便每个id的类型和类型val的所有组合都是按行的。我认为这一定是PKG的工作,但除了错误之外,我完全没有生成任何其他错误。结果数据结构(有点冗余)是这样的(希望我答对了!)其中,类型对(由类型val的组合给出)是列t1和t2,它们的相关值(val在df中)是val t1和val t2-列名称是任意的:

    id  type_t1 type_t2 val_t1  val_t2
1   a   1   1   1   7
2   a   1   2   1   9
3   a   1   3   1   11
4   a   2   1   3   7
5   a   2   2   3   9
6   a   2   3   3   11
7   a   3   1   5   7
8   a   3   2   5   9
9   a   3   3   5   11
10  b   1   1   2   8
11  b   1   2   2   10
12  b   1   3   2   12
13  b   2   1   4   8
14  b   2   2   4   10
15  b   2   3   4   12
16  b   3   1   6   8
17  b   3   2   6   10
18  b   3   3   6   12

更新

请注意(@Sotos)

> spread(df, type, val)
  id type_val t1 t2
1  a        1  1  7
2  a        2  3  9
3  a        3  5 11
4  b        1  2  8
5  b        2  4 10
6  b        3  6 12

不是期望的输出-它无法提供由df中的类型和类型定义的宽格式


共有2个答案

洪飞驰
2023-03-14

这里有一种更通用的方法,可以处理任意数量的唯一类型:

library(dplyr)

# This function takes a list of dataframes (.data) and merges them by ID
reduce_merge <- function(.data, ID) {
    return(Reduce(function(x, y) merge(x, y, by = ID), .data))
}

# This function renames the cols columns in .data by appending _identifier
batch_rename <- function(.data, cols, identifier, sep = '_') {
    return(plyr::rename(.data, sapply(cols, function(x){
        x = paste(x, .data[1, identifier], sep = sep)
    })))
}

# This function creates a list of subsetted dataframes
# (subsetted by values of key),
# uses batch_rename() to give each dataframe more informative column names,
# merges them together, and returns the columns you'd like in a sensible order
multi_spread <- function(.data, grp, key, vals) {
    .data %>%
        plyr::dlply(key, subset) %>%
        lapply(batch_rename, vals, key) %>%
        reduce_merge(grp) %>%
        select(-starts_with(paste0(key, '.'))) %>%
        select(id, sort(setdiff(colnames(.), c(grp, key, vals))))
}

# Your example
df <- data.frame(id=rep(letters[1:2],6), 
                 type=c(rep('t1',6), rep('t2',6)),
                 type_val=rep(c(1,1,2,2,3,3),2),
                 val=1:12)

df %>% multi_spread('id', 'type', c('type_val', 'val'))

   id type_val_t1 type_val_t2 val_t1 val_t2
1   a           1           1      1      7
2   a           1           2      1      9
3   a           1           3      1     11
4   a           2           1      3      7
5   a           2           2      3      9
6   a           2           3      3     11
7   a           3           1      5      7
8   a           3           2      5      9
9   a           3           3      5     11
10  b           1           1      2      8
11  b           1           2      2     10
12  b           1           3      2     12
13  b           2           1      4      8
14  b           2           2      4     10
15  b           2           3      4     12
16  b           3           1      6      8
17  b           3           2      6     10
18  b           3           3      6     12

# An example with three unique values of 'type'
df <- data.frame(id = rep(letters[1:2], 9), 
                 type = c(rep('t1', 6), rep('t2', 6), rep('t3', 6)),
                 type_val = rep(c(1, 1, 2, 2, 3, 3), 3),
                 val = 1:18)

df %>% multi_spread('id', 'type', c('type_val', 'val'))

   id type_val_t1 type_val_t2 type_val_t3 val_t1 val_t2 val_t3
1   a           1           1           1      1      7     13
2   a           1           1           2      1      7     15
3   a           1           1           3      1      7     17
4   a           1           2           1      1      9     13
5   a           1           2           2      1      9     15
6   a           1           2           3      1      9     17
7   a           1           3           1      1     11     13
8   a           1           3           2      1     11     15
9   a           1           3           3      1     11     17
10  a           2           1           1      3      7     13
11  a           2           1           2      3      7     15
12  a           2           1           3      3      7     17
13  a           2           2           1      3      9     13
14  a           2           2           2      3      9     15
15  a           2           2           3      3      9     17
16  a           2           3           1      3     11     13
17  a           2           3           2      3     11     15
18  a           2           3           3      3     11     17
19  a           3           1           1      5      7     13
20  a           3           1           2      5      7     15
21  a           3           1           3      5      7     17
22  a           3           2           1      5      9     13
23  a           3           2           2      5      9     15
24  a           3           2           3      5      9     17
25  a           3           3           1      5     11     13
26  a           3           3           2      5     11     15
27  a           3           3           3      5     11     17
28  b           1           1           1      2      8     14
29  b           1           1           2      2      8     16
30  b           1           1           3      2      8     18
31  b           1           2           1      2     10     14
32  b           1           2           2      2     10     16
33  b           1           2           3      2     10     18
34  b           1           3           1      2     12     14
35  b           1           3           2      2     12     16
36  b           1           3           3      2     12     18
37  b           2           1           1      4      8     14
38  b           2           1           2      4      8     16
39  b           2           1           3      4      8     18
40  b           2           2           1      4     10     14
41  b           2           2           2      4     10     16
42  b           2           2           3      4     10     18
43  b           2           3           1      4     12     14
44  b           2           3           2      4     12     16
45  b           2           3           3      4     12     18
46  b           3           1           1      6      8     14
47  b           3           1           2      6      8     16
48  b           3           1           3      6      8     18
49  b           3           2           1      6     10     14
50  b           3           2           2      6     10     16
51  b           3           2           3      6     10     18
52  b           3           3           1      6     12     14
53  b           3           3           2      6     12     16
54  b           3           3           3      6     12     18
欧阳昊焱
2023-03-14

这个怎么样:

df1=df[df$type=="t1",]
df2=df[df$type=="t2",]

DF=merge(df1,df2,by="id")
DF=DF[,-c(2,5)]
colnames(DF)<-c("id", "type_t1", "val_t1","type_t2",   "val_t2")
 类似资料:
  • 我试图将一个数据列表一分为二,但我不知道如何正确执行。 当我使用dput(a)时,我的数据如下 结构(列表)(V1=结构(c(1L、9L、10L、11L、12L、13L、14L、15L、16L、2L、3L、4L、5L、6L、7L、8L)。标签=c(“1\t1200.30”,“10\t1305.80”,“11\t1263.02”,“12\t1312.67”,“13\t1229.85”,“14\t12

  • 给定一个< code>n数和sum 的列表,将这些数分成< code >两个组,使得每组中的数之和小于或等于s。如果可以分组,则打印< code>YES,如果不能分组,则打印< code>NO。 例如,如果< code>n=3,s=4和< code>n数是< code>2,4,2。在这种情况下,输出为< code>YES,因为可以形成两个组< code>(2,2)和(4)。 我的解决方案如下。 是

  • 我在excel中有一个列,其中包含名字、姓氏和职位名称的混合。唯一可以观察到的模式是——在每一组3行中,每第1行是名字,第2行是姓氏,第3行是工作标题。我想创建3个不同的列,并隔离此数据示例数据: 我想要:约翰,布什,经理,作为一行,分别放在名字,姓氏和职务下面的三个不同的栏中。像- 我们如何才能完成这项任务?

  • 输入的dput() 结构(列表(Varname=structure(1:6,.标签=c(“A”,“B”,“c”,“D”,“E”,“F”),类=“因子”),成分=结构(c(3L,1L,1L,4L,2L,1L),标签=c(“”,“A,c”,“B”,“c”),类=“因子”),名字=结构(c(5L,3L,2L,4L,6L),标签=c(“”,“鲍勃”,“凯茜”,“迪克,南希”,“杰克,布鲁斯”,“曼迪”),

  • 我有两个系列和具有相同的(非连续的)索引。如何将和组合为DataFrame中的两列,并将其中一个索引保留为第三列?

  • 本文向大家介绍如何将R中的数据帧随机分成多个部分?,包括了如何将R中的数据帧随机分成多个部分?的使用技巧和注意事项,需要的朋友参考一下 当数据帧很大时,我们可以将其随机分为多个部分。当我们要部分分析数据时,可能需要这样做。我们可以借助split函数和sample函数来随机选择值。 示例 考虑以R为底的树数据 将树木数据分为三部分- 考虑基数R中的女性数据- 将女性数据分为两部分-