R语言 使用基于列的长轴透视

hs1ihplo  于 2023-03-27  发布在  其他
关注(0)|答案(3)|浏览(168)

我尝试透视数据集,以便长数据集中的值基于其中一列中的值。下面是数据的示例:

testdf <- data.frame('b'=rep(1:5, each=2), 'x'=rnorm(10, 0),'y'=rnorm(10, c(5,10)),'z'=rnorm(5, c(10,20)),'a'=rep(c(1, 2), 5))

如果我长轴旋转并排除b,我得到:

testdflong <- tidyr::pivot_longer(testdf, !c(b), names_to='lines', values_to='values')

它为每个a=c(1,2)重复每个值x,y,z。我想做的是只根据a选择z的值。我知道我可以过滤宽数据,但在真实的用例中a可能有2个以上的值,z也是如此,我不想过滤每个'a'上的宽数据。

resultdf <- testdf %>% filter(a==1)
resultdf <- bind_cols(resultdf, testdf %>% filter(a==2) %>% dplyr::select(z))
resultdflong <- tidyr::pivot_longer(resultdf, !c(b), names_to='lines', values_to='values')

但是我想跳过过滤和bind_cols步骤。

clj7thdc

clj7thdc1#

testdf %>%
  pivot_longer(-c(a,b))  %>%
  pivot_wider(names_from = c(name, a), values_from = value) %>%
  pivot_longer(-b, names_to = "lines", values_to = "values") %>%
  filter(lines %>% str_ends("1") | lines %>% str_starts("z")) %>%
  complete(b, lines = c("a", unique(lines)), fill = list(values = 1))

结果

# A tibble: 25 × 3
       b lines values
   <int> <chr>  <dbl>
 1     1 a      1    
 2     1 x_1   -0.158
 3     1 y_1    4.11 
 4     1 z_1    9.62 
 5     1 z_2   19.1  
 6     2 a      1    
 7     2 x_1   -0.820
 8     2 y_1    6.13 
 9     2 z_1    9.25 
10     2 z_2   17.8  
# … with 15 more rows
yvfmudvl

yvfmudvl2#

我的解决方案比Jon的解决方案稍微瘦一点:

testdf1 <- testdf %>% 
              dplyr::select(b, z, a) %>% 
              tidyr::pivot_wider(names_from = a, values_from=z)
testdf2 <- bind_cols(testdf %>% filter(a==1) %>% 
              dplyr::select(b, x, y), testdfw %>% 
              dplyr::select(!b))
testd2long <- tidyr::pivot_longer(testdf2, !b, names_to='lines', values_to='values')
fv2wmkja

fv2wmkja3#

我们可以将'x','y'中的值替换为NA,其中a不等于1,然后利用pivot_longer中的values_drop_na删除长格式数据集中的这些行

library(dplyr) # version>= 1.1.0
library(tidyr)
testdf %>%
   mutate(across(x:y, ~ case_match(a, 1~ .x))) %>%
   pivot_longer(cols = -b, names_to = 'lines', values_to = 'values', 
   values_drop_na = TRUE)%>% 
   filter((values == 1 & lines == 'a')| lines != 'a' )
  • 输出
# A tibble: 25 × 3
       b lines values
   <int> <chr>  <dbl>
 1     1 x     -1.06 
 2     1 y      4.12 
 3     1 z      8.61 
 4     1 a      1    
 5     1 z     20.7  
 6     2 x     -0.148
 7     2 y      6.33 
 8     2 z     10.3  
 9     2 a      1    
10     2 z     20.7  
# … with 15 more rows

相关问题