【问题标题】:How to Pivot Wider a NoSQL data in R [duplicate]如何在 R 中更广泛地旋转 NoSQL 数据
【发布时间】:2020-08-18 14:38:26
【问题描述】:

我正在处理 NoSQL 数据,我需要在 R 中进行数据透视。

样本数据:

structure(list(timestamp = structure(c(1595709882, 1595709882, 
1595709931, 1595709931, 1595710021, 1595710023, 1595710023, 1595710027, 
1595710157, 1595710157, 1595710277, 1595710277, 1595710337, 1595710337, 
1595710397, 1595710397, 1595710457, 1595710457, 1595710517, 1595710517
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), value = c("3000", 
"160", "160", "3000", "6000", "6000", "160", "6000", "6000", 
"160", "160", "6000", "6000", "160", "6000", "160", "6000", "160", 
"6000", "160"), variable = c("ENGINE_RPM", "VEHICLE_SPEED", "VEHICLE_SPEED", 
"ENGINE_RPM", "ENGINE_RPM", "ENGINE_RPM", "VEHICLE_SPEED", "ENGINE_RPM", 
"ENGINE_RPM", "VEHICLE_SPEED", "VEHICLE_SPEED", "ENGINE_RPM", 
"ENGINE_RPM", "VEHICLE_SPEED", "ENGINE_RPM", "VEHICLE_SPEED", 
"ENGINE_RPM", "VEHICLE_SPEED", "ENGINE_RPM", "VEHICLE_SPEED")), row.names = c(NA, 
-20L), class = c("tbl_df", "tbl", "data.frame"))


timestamp          value    variable
7/25/2020 20:44:42  3000    ENGINE_RPM
7/25/2020 20:44:42  160 VEHICLE_SPEED
7/25/2020 20:45:31  160 VEHICLE_SPEED
7/25/2020 20:45:31  3000    ENGINE_RPM
7/25/2020 20:47:01  6000    ENGINE_RPM
7/25/2020 20:47:03  6000    ENGINE_RPM
7/25/2020 20:47:03  160 VEHICLE_SPEED
7/25/2020 20:47:07  6000    ENGINE_RPM
7/25/2020 20:49:17  6000    ENGINE_RPM
7/25/2020 20:49:17  160 VEHICLE_SPEED
7/25/2020 20:51:17  160 VEHICLE_SPEED
7/25/2020 20:51:17  6000    ENGINE_RPM
7/25/2020 20:52:17  6000    ENGINE_RPM
7/25/2020 20:52:17  160 VEHICLE_SPEED
7/25/2020 20:53:17  6000    ENGINE_RPM
7/25/2020 20:53:17  160 VEHICLE_SPEED
7/25/2020 20:54:17  6000    ENGINE_RPM
7/25/2020 20:54:17  160 VEHICLE_SPEED
7/25/2020 20:55:17  6000    ENGINE_RPM
7/25/2020 20:55:17  160 VEHICLE_SPEED

如果我们查看示例数据,某些时间戳同时具有 RPM 和 SPEED,而很少有时间戳只有其中之一。

我需要那些具有 2 个时间戳的行,因为它们同时具有车速和 RPM,我稍后可以在特定时间旋转以查看车辆的速度和发动机的 RPM。

我正在查看的输出是:

timestamp           ENGINE_RPM  VEHICLE_SPEED
7/25/2020 20:44:42  3000        160
7/25/2020 20:45:31  3000        160
7/25/2020 20:47:03  6000        160
7/25/2020 20:49:17  6000        160
7/25/2020 20:51:17  6000        160
7/25/2020 20:52:17  6000        160
7/25/2020 20:53:17  6000        160
7/25/2020 20:54:17  6000        160
7/25/2020 20:55:17  6000        160

我使用的查询是:

data %>% group_by(timestamp, variable, value) %>% 
        mutate(row = row_number()) %>% filter(n() == 2) %>% 
          pivot_wider(names_from = variable, values_from = value) %>% select(-row)

我得到的输出是:

# A tibble: 8 x 3
# Groups:   timestamp [4]
  timestamp           VEHICLE_SPEED ENGINE_RPM
  <dttm>              <chr>         <chr>     
1 2020-08-05 16:09:02 5             NA        
2 2020-08-05 16:09:02 5             NA        
3 2020-08-06 18:32:33 15            NA        
4 2020-08-06 18:32:33 15            NA        
5 2020-08-06 18:32:52 25            NA        
6 2020-08-06 18:32:52 25            NA        
7 2020-08-07 12:03:53 NA            1500      
8 2020-08-07 12:03:53 NA            1500      
> 

有人可以告诉我如何获得所需的输出。

【问题讨论】:

    标签: r dplyr tidyr


    【解决方案1】:

    您可以在使用pivot_wider 后使用na.omit 函数使您的数据更宽:

    dat %>%
        pivot_wider(names_from = variable, values_from = value) %>%
        na.omit()
    
      timestamp           ENGINE_RPM VEHICLE_SPEED
      <dttm>              <chr>      <chr>        
    1 2020-07-25 20:44:42 3000       160          
    2 2020-07-25 20:45:31 3000       160          
    3 2020-07-25 20:47:03 6000       160          
    4 2020-07-25 20:49:17 6000       160          
    5 2020-07-25 20:51:17 6000       160          
    6 2020-07-25 20:52:17 6000       160          
    7 2020-07-25 20:53:17 6000       160          
    8 2020-07-25 20:54:17 6000       160          
    9 2020-07-25 20:55:17 6000       160 
    

    【讨论】:

    • 我收到此错误:警告消息:value 中的值不是唯一标识的;输出将包含列表列。 * 使用values_fn = list(value = list) 禁止此警告。 * 使用values_fn = list(value = length) 确定重复出现的位置 * 使用values_fn = list(value = summary_fun) 总结重复
    • 单个时间戳是否可能有多个行具有相同的变量?您可以通过count(dat, timestamp, variable) 进行检查
    • 是的,这就是为什么我在我的问题中提到“某些时间戳同时具有 RPM 和 SPEED,而很少有时间戳只有其中之一”。时间戳可以有一行用于 RPM,另一行用于 SPEED。但我需要这些行,这样我就可以以这样一种方式进行旋转,即时间戳、RPM 和 SPEED 各有一列。
    • 不,我说的是对于单个时间戳,同一个变量会有多行的情况。例如,对于时间戳 1,RPM 可以有两行。 count(dat, timestamp, variable) %&gt;% filter(n &gt; 1) 返回多少行?
    • 哦,所以我运行了 count(data, timestamp, variable),我得到了略多于 30k 行,对于 60 奇数行,我得到“n”的值为 2。我假设这意味着一个时间戳RPM 或 SPEED 可以有两行?
    【解决方案2】:

    你可以试试这个

    library(tidyr)
    library(dplyr)
    df2 <- df %>% 
      distinct(.) %>% 
      pivot_wider(names_from = variable, values_from = value) %>% 
      filter(!is.na(VEHICLE_SPEED))
    

    或者

    df2 <- df %>% 
      distinct(.) %>% 
      spread(variable, value) %>% 
      filter(!is.na(VEHICLE_SPEED))
        # timestamp           ENGINE_RPM VEHICLE_SPEED
    # <dttm>              <chr>      <chr>        
    # 1 2020-07-25 20:44:42 3000       160          
    # 2 2020-07-25 20:45:31 3000       160          
    # 3 2020-07-25 20:47:03 6000       160          
    # 4 2020-07-25 20:49:17 6000       160          
    # 5 2020-07-25 20:51:17 6000       160          
    # 6 2020-07-25 20:52:17 6000       160          
    # 7 2020-07-25 20:53:17 6000       160          
    # 8 2020-07-25 20:54:17 6000       160          
    # 9 2020-07-25 20:55:17 6000       160 
    

    【讨论】:

    • 对于选项 1),对于选项 2),我收到与上述相同的错误:错误:每行输出必须由唯一的键组合标识。密钥共享 118 行:
    • 让我澄清一下。您是刚刚运行这些代码行还是添加了更多行?还是您运行了必要的库?
    • 我运行了你提到的,没有得到“你运行了必要的库”。
    • library(tidyr)library(dplyr) 是我提到的。我想你可以再检查一次,也许你错过了什么。
    • 是的,我已经加载了这些库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2020-12-20
    相关资源
    最近更新 更多