将多列收集到一个键和两个值中

时间:2020-09-30 13:05:25

标签: r

我需要将多个列收集到一个键和两个值中。我在这里遇到了很多类似的问题,但是我无法重现答案,因为它们非常具体,恕我直言。如果有一个可以回答我的问题,那么我对链接感到满意。

示例df:

df <- data.frame(semester=rep(1:6),
                 Anna_try1=c(1,2,2,1,4,2),
                 Lena_try1=c(3,4,2,3,2,1),
                 Anna_try2=c(2,3,1,2,1,4),
                 Lena_try2=c(2,4,2,1,5,2))

如下所示:

enter image description here

我需要这样的东西:

enter image description here

5 个答案:

答案 0 :(得分:3)

如果您有更好的列名,则可以轻松使用node

但是我们可以先解决这个问题。

reshape

答案 1 :(得分:3)

您可以使用tidyr::pivot_longer

tidyr::pivot_longer(df, 
                    cols = -semester, 
                    names_to = c('name', '.value'),
                    names_sep = '_')

#   semester name   try1  try2
#      <int> <chr> <dbl> <dbl>
# 1        1 Anna      1     2
# 2        1 Lena      3     2
# 3        2 Anna      2     3
# 4        2 Lena      4     4
# 5        3 Anna      2     1
# 6        3 Lena      2     2
# 7        4 Anna      1     2
# 8        4 Lena      3     1
# 9        5 Anna      4     1
#10        5 Lena      2     5
#11        6 Anna      2     4
#12        6 Lena      1     2             

答案 2 :(得分:2)

尝试重塑形状,将变量分成所需的新值,然后重塑形状。下面是使用tidyverse函数的代码:

library(tidyverse)
#Code
df <- df %>% pivot_longer(-semester) %>%
  separate(name,c('name','try'),sep = '_') %>%
  mutate(try=paste0('grade_',try)) %>%
  pivot_wider(names_from = try,values_from=value) %>%
  arrange(name,semester)

输出:

# A tibble: 12 x 4
   semester name  grade_try1 grade_try2
      <int> <chr>      <dbl>      <dbl>
 1        1 Anna           1          2
 2        2 Anna           2          3
 3        3 Anna           2          1
 4        4 Anna           1          2
 5        5 Anna           4          1
 6        6 Anna           2          4
 7        1 Lena           3          2
 8        2 Lena           4          4
 9        3 Lena           2          2
10        4 Lena           3          1
11        5 Lena           2          5
12        6 Lena           1          2

答案 3 :(得分:2)

这不是最优雅的解决方案,但可以完成工作:

library(data.table)
library(stringr)

df1 <- setDT(df[, -grep("try1", colnames(df))])
df2 <- setDT(df[, -grep("try2", colnames(df))])

melted1 <- melt(df1, id.vars=c("semester"), variable.name = "name", value.name = "grade_try2")
melted2 <- melt(df2, id.vars=c("semester"), variable.name = "name", value.name = "grade_try1")

melted1$name <- str_sub(melted1$name, -str_length(melted1$name), -6)
melted2$name <- str_sub(melted2$name, -str_length(melted2$name), -6)

final <- melted2[melted1, on = .(semester = semester, name = name)]

答案 4 :(得分:0)

我们可以将getLevel = (exp) => { let res; let keys = Object.keys(levels); let start = 0; let end = keys.length - 1; let index = 0; while(start <= end){ let mid = Math.floor((end + start) / 2); if(levels[keys[mid]] <= exp){ start = mid + 1; index = mid; } else { end = mid - 1; } } if(Math.abs(levels[keys[index]] - exp) > Math.abs(levels[keys[index+1]] - exp)){ res = keys[index+1]; } else { res = keys[index]; } return res; } 中的/etc/vim/vimrcautocmd Filetype json setlocal ts=2 sw=2 expandtab 一起使用

melt