【问题标题】:(Amateur) data manipulation in R: variable levels as new column with its values from another columnR中的(业余)数据操作:变量级别作为新列,其值来自另一列
【发布时间】:2020-04-26 22:37:54
【问题描述】:

我想创建一个新列,从type 中提取“b”和“c”并将value 放入该列。中间还有其他随机列应该保留,我刚刚命名为random


id <- c("1", "1", "1", "1","2", "2", "2", "2", "3", "3", "3", "3")
type <- c("a", "a", "b", "c", "a", "a", "b", "c", "a", "a", "b", "c")
random <- c("random")
value <- c("1", "2", "50", "100", "4", "5", "55", "110", "2.5", "3", "53", "105")

df <- data.frame(id, type, random, value)

  id type random value
1   1    a random     1
2   1    a random     2
3   1    b random    50
4   1    c random   100
5   2    a random     4
6   2    a random     5
7   2    b random    55
8   2    c random   110
9   3    a random   2.5
10  3    a random     3
11  3    b random    53
12  3    c random   105

我想要的是:

  id2 type2 random value2  b   c
1   1     a random      1 50 100
2   1     a random      2 50 100
3   2     a random      4 55 110
4   2     a random      5 55 110
5   3     a random    2.5 53 105
6   3     a random      3 53 105

非常感谢一些想法!最好的,

【问题讨论】:

  • 你能用更多的'id展示一个更一般的例子
  • 嗨@akrun,谢谢你的帮助,你是最棒的!!!我已经编辑了帖子,我认为现在更清楚了。你能确认一下吗?
  • @Mark-Marijn 假设 'id' 的第二个值是 type' 'b',它的值是 85。那么预期的输出是什么,即不是 value = 5,而是值 = 85
  • @Mark-Marjin 你能检查我更新的解决方案吗

标签: r dataframe data-manipulation


【解决方案1】:

我们可以按“id”分组,通过提取“值”来创建“b”列,其中“类型”为“b”(假设每个组的单个值“b”)ungroup 并删除'type' 为 'b' 的行

library(dplyr)
df %>%
    group_by(id) %>%
    mutate(b = value[type == 'b']) %>% 
    ungroup %>% 
    filter(type != 'b')
# A tibble: 4 x 5
#  id    type  keepthis value b    
#  <fct> <fct> <fct>    <fct> <fct>
#1 1     a     keep     4     95   
#2 1     a     keep     5     95   
#3 2     a     keep     3     94   
#4 2     a     keep     5     94  

更新

基于更新的数据集,我们可以 filter 使用 'b'、'c' 的 'type',使用原始数据集 filter 使用 pivot_widerleft_join 重塑为 'wide' 格式只用 'type' 'a' 编辑

library(tidyr)
df %>%
     filter(type %in% c('b', 'c'))  %>% 
     pivot_wider(names_from = type, values_from = value) %>%
     left_join(df %>% 
             filter(type  == 'a'))
# A tibble: 6 x 6
#  id    random b     c     type  value
#* <fct> <fct>  <fct> <fct> <fct> <fct>
#1 1     random 50    100   a     1    
#2 1     random 50    100   a     2    
#3 2     random 55    110   a     4    
#4 2     random 55    110   a     5    
#5 3     random 53    105   a     2.5  
#6 3     random 53    105   a     3    

使用更新的数据集,代码将是

df %>%
    filter(scale_id %in% c('IM', 'RT')) %>% 
    select(Title, Task, task_id, scale_id, data_value) %>% 
    pivot_wider(names_from = scale_id, values_from  = data_value) %>% 
    left_join(df %>% 
                  filter(! scale_id %in% c('IM', 'RT')) %>% 
                  group_by(task_id) %>%
                  slice(which.max(data_value)))

【讨论】:

  • @Marc-Marijn I. 根据示例假设每个“id”只有一个“b”元素
  • @Marc-Marijn 您能否更新您的帖子,其中每个“id”都有多个“b”值,在这种情况下,将选择什么
  • @Marc-Marijn 你能试试df %&gt;% filter(type == 'b') %&gt;% mutate(type = 'a') %&gt;% rename(b = value) %&gt;% bind_rows(df %&gt;% filter(type != 'b'), .) %&gt;% group_by(id) %&gt;% fill(b, .direction = 'updown') %&gt;% ungroup %&gt;% filter(!is.na(value))
  • @Marc-Marijn 能否请您更新一下这种情况,因为我想知道将选择哪些值,因为它会导致长度问题
  • @Marc-Marijn 如果您在更一般的情况及其预期输出中进行所有这些更改会更好,因为从我这边来看,无法理解预期输出
猜你喜欢
  • 1970-01-01
  • 2020-07-24
  • 2015-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多