如何使用两个规则从一个变量创建新变量

时间:2019-01-31 22:34:34

标签: r dataframe tidyverse tidyr reshape2

希望您能从一个变量中创建新变量。

特别是,我需要帮助来同时为每个IDE的各个列创建一行,其中E的每个新列(即{{1 }},E1E2)包含E3每行的E值。我尝试在ID后跟melt的位置执行此操作,但出现错误:

  

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

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

#data

E

#我的尝试

E3

#期望的输出

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))

在此先感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您可以使用dcast中的data.table

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)的作用。

答案 1 :(得分:1)

对于那些寻求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。