R语言 如何查找行的第一个非空值的列名

6yoyoihd  于 2022-12-20  发布在  其他
关注(0)|答案(2)|浏览(167)

我正在处理一个查询的数据框,它看起来像:
| 用户ID| 2012年1月1日|2012年2月1日|2012年2月1日|
| - ------| - ------| - ------| - ------|
| 细胞1|不适用|第二章|不适用|
| 单元格3| 1个|不适用|五个|
我希望找到第一个非空列(不包括User ID列)的日期(列名)、最后一个非空列的名称以及每个用户ID的这些日期之间的持续时间。
谢谢大家!
我试过了

df$min_date<-apply(df[-1], 1, function(x) 
   x[which.min(which(is.na(x) == FALSE))])

以及

df$min_date<-apply(df[-1], 1, function(x) 
   colnames(x[min(which(is.na(x) == FALSE))]))

但没有成功

wz3gfoph

wz3gfoph1#

不如这样:

library(dplyr) 
library(tidyr)
d <- tibble::tribble(
  ~"User ID",   ~"2012-01-01",  ~"2012-02-01",  ~"2012-02-01", 
"Cell 1",   NA, 2,  NA,
"Cell 3",   1,  NA, 5)
d %>% 
  pivot_longer(-1, names_to="date", values_to = "vals") %>%
  na.omit() %>% 
  mutate(date = lubridate::ymd(date)) %>% 
  group_by(`User ID`) %>% 
  summarise(first = first(date), 
            last = last(date)) %>% 
  mutate(diff = last - first)
#> # A tibble: 2 × 4
#>   `User ID` first      last       diff   
#>   <chr>     <date>     <date>     <drtn> 
#> 1 Cell 1    2012-02-01 2012-02-01  0 days
#> 2 Cell 3    2012-01-01 2012-02-01 31 days

reprex package(v2.0.1)于2022年12月13日创建
这里有一个基本的R方式(尽管使用了lubridate),它更符合你最初的想法:

d <- tibble::tribble(
  ~"User ID",   ~"2012-01-01",  ~"2012-02-01",  ~"2012-02-01", 
"Cell 1",   NA, 2,  NA,
"Cell 3",   1,  NA, 5)
d <- tibble::tribble(
  ~"User ID",   ~"2012-01-01",  ~"2012-02-01",  ~"2012-02-01", 
  "Cell 1", NA, 2,  NA,
  "Cell 3", 1,  NA, 5)

mind <- apply(d[,-1], 1, function(x)
  colnames(d[,-1])[min(which(!is.na(x)))])
maxd <- apply(d[,-1], 1, function(x)
  colnames(d[,-1])[max(which(!is.na(x)))])

d$min_date <- lubridate::ymd(mind)
d$max_date <- lubridate::ymd(maxd)
d$diff <- d$max_date - d$min_date

d
#> # A tibble: 2 × 7
#>   `User ID` `2012-01-01` `2012-02-01` `2012-02-01` min_date   max_date   diff   
#>   <chr>            <dbl>        <dbl>        <dbl> <date>     <date>     <drtn> 
#> 1 Cell 1              NA            2           NA 2012-02-01 2012-02-01  0 days
#> 2 Cell 3               1           NA            5 2012-01-01 2012-02-01 31 days

reprex package(v2.0.1)于2022年12月13日创建

5jdjgkvh

5jdjgkvh2#

下面是一个tidyverse选项:
注意你使用的是非语法名称,而且第3列和第4列的名称相同。这在R中不起作用:

library(dplyr)
library(tidyr)

df %>% 
  mutate(across(-c(User, ID), ~case_when(!is.na(.) ~ cur_column()), .names = 'new_{col}')) %>%
  unite(non_null, starts_with('new'), na.rm = TRUE, sep = ' ') %>% 
  mutate(non_null = sub(" .*", "", non_null))
User ID X2012.01.01 X2012.02.01 X2012.02.01.1    non_null
1 Cell  1          NA           2            NA X2012.02.01
2 Cell  3           1          NA             5 X2012.01.01

相关问题