【问题标题】:how to create new variables from one variable using two rules如何使用两个规则从一个变量创建新变量
【发布时间】:2019-06-25 11:34:49
【问题描述】:

对于从一个变量创建新变量的任何帮助,我将不胜感激。

具体来说,我需要帮助同时为每个IDE 的各个列创建一行,其中E 的每个新列,(即E1E2、@ 987654328@) 包含E 每行ID 的值。我尝试这样做 melt 后跟 spread 但我得到了错误:

错误:行 (4, 7, 9), (1, 3, 6), (2, 5, 8) 的标识符重复

此外,我尝试了讨论herehere 的解决方案,但这些解决方案不适用于我的情况,因为我需要能够为行(4、1、2)、(7、3)创建row identifiers , 5) 和 (9, 6, 8)。也就是说,E 用于行 (4, 1, 2) 应命名为 E1, E 用于行 (7, 3, 5) 应命名为 E2, E 用于行 (9, 6 , 8) 应命名为E3,以此类推。

#data

dT<-structure(list(A = c("a1", "a2", "a1", "a1", "a2", "a1", "a1", 
    "a2", "a1"), B = c("b2", "b2", "b2", "b1", "b2", "b2", "b1", 
    "b2", "b1"), ID = c("3", "4", "3", "1", "4", "3", "1", "4", "1"
    ), E = c(0.621142094943352, 0.742109450696123, 0.39439152996948, 
    0.40694392882818, 0.779607277916503, 0.550579323666347, 0.352622183880119, 
    0.690660491345867, 0.23378944873769)), class = c("data.table", 
    "data.frame"), row.names = c(NA, -9L))

#我的尝试

    A  B ID         E
1: a1 b2  3 0.6211421
2: a2 b2  4 0.7421095
3: a1 b2  3 0.3943915
4: a1 b1  1 0.4069439
5: a2 b2  4 0.7796073
6: a1 b2  3 0.5505793
7: a1 b1  1 0.3526222
8: a2 b2  4 0.6906605
9: a1 b1  1 0.2337894

aTempDF <- melt(dT, id.vars = c("A", "B", "ID")) )

    A  B  ID variable    value
1: a1 b2  3        E 0.6211421
2: a2 b2  4        E 0.7421095
3: a1 b2  3        E 0.3943915
4: a1 b1  1        E 0.4069439
5: a2 b2  4        E 0.7796073
6: a1 b2  3        E 0.5505793
7: a1 b1  1        E 0.3526222
8: a2 b2  4        E 0.6906605
9: a1 b1  1        E 0.2337894

aTempDF%>%spread(variable, value)

Error: Duplicate identifiers for rows (4, 7, 9), (1, 3, 6), (2, 5, 8)

#expected 输出

    A  B  ID       E1           E2           E3
1: a1 b2  3        0.6211421    0.3943915    0.5505793
2: a2 b2  4        0.7421095    0.7796073    0.6906605 
3: a1 b1  1        0.4069439    0.3526222    0.2337894

提前感谢您的帮助。

【问题讨论】:

  • 原来的问题已经回答了。请创建一个新问题,而不是使现有答案无效。

标签: r dataframe tidyverse tidyr reshape2


【解决方案1】:

您可以从data.table 使用dcast

library(data.table)
dcast(dT, A + B + ID ~ paste0("E", rowid(ID)))
#   A  B ID        E1        E2        E3
#1 a1 b1  1 0.4069439 0.3526222 0.2337894
#2 a1 b2  3 0.6211421 0.3943915 0.5505793
#3 a2 b2  4 0.7421095 0.7796073 0.6906605

您需要首先创建正确的“时间变量”,这就是 rowid(ID) 所做的。

【讨论】:

  • 嗨@mar​​kus。奇怪的是,该解决方案似乎适用于小型数据集(样本),但不适用于我想要使用的实际数据集。我已经编辑并附加了更大的数据。提前感谢您的帮助。
【解决方案2】:

对于那些正在寻找tidyverse 解决方案的人:

library(tidyverse)

dT <- structure(
  list(
    A = c("a1", "a2", "a1", "a1", "a2", "a1", "a1", "a2", "a1"),
    B = c("b2", "b2", "b2", "b1", "b2", "b2", "b1", "b2", "b1"),
    ID = c("3", "4", "3", "1", "4", "3", "1", "4", "1"),
    E = c(0.621142094943352, 0.742109450696123, 0.39439152996948, 0.40694392882818,
          0.550579323666347, 0.352622183880119, 0.690660491345867, 0.23378944873769,
          0.779607277916503)),
  class = c("data.table", 
            "data.frame"),
  row.names = c(NA, -9L))
dT %>% 
  as_tibble() %>%  # since dataset is a data.table object
  group_by(A, B, ID) %>% 
  # Just so columns are "E1", "E2", etc.
  mutate(rn = glue::glue("E{row_number()}")) %>% 
  ungroup() %>% 
  spread(rn, E) %>%
  # not necessary, just making output in the same order as your expected output
  arrange(desc(B)) 
# A tibble: 3 x 6
#  A     B     ID       E1    E2    E3
#  <chr> <chr> <chr> <dbl> <dbl> <dbl>
#1 a1    b2    3     0.621 0.394 0.551
#2 a2    b2    4     0.742 0.780 0.691
#3 a1    b1    1     0.407 0.353 0.234

如已接受的答案中所述,您首先需要一个“关键”变量来传播。这是使用 row_number()glue 创建的,其中 glue 只是为您提供正确的 E1、E2 等变量名称。

group_by 部分只是确保行号与 A、B 和 ID 相关。


编辑 tidyr >= 1.0.0

(不那么)新的 pivot_ 函数取代了 gatherspread 并消除了将 glue 新变量名放在一起变化的需要。

dT %>% 
  as_tibble() %>%  # since dataset is a data.table object
  group_by(A, B, ID) %>% 
  # no longer need to glue (or paste) the names together but still need a row number
  mutate(rn = row_number()) %>% 
  ungroup() %>% 
  pivot_wider(names_from = rn, values_from = E, names_glue = "E{.name}") %>% # names_glue argument allows for easy transforming of the new variable names
  # not necessary, just making output in the same order as your expected output
  arrange(desc(B)) 
# A tibble: 3 x 6
#  A     B     ID       E1    E2    E3
#  <chr> <chr> <chr> <dbl> <dbl> <dbl>
#1 a1    b2    3     0.621 0.394 0.551
#2 a2    b2    4     0.742 0.780 0.691
#3 a1    b1    1     0.407 0.353 0.234

【讨论】:

    猜你喜欢
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    相关资源
    最近更新 更多