R:根据 R 中的列名获取行值

R: Get row values based on column name in R

我有这样一个数据框:

ID Q4_1 Q4_2 Q4_3 Q4_4 Q4_5
1  4    3    1
2  1    3
3  3    1    2
4  5

我能知道如何根据列的前缀重新排列行值以获得类似这样的结果吗?

ID Q4_1 Q4_2 Q4_3 Q4_4 Q4_5
1  1         3    4
2  1         3
3  1    2    3
4                      5

这是一个基本的 R 方法。请注意,我已将您输入中的空 space 替换为 NA.

这个解决方案的核心是使用 lapply 遍历数据框中的所有行,然后使用 ifelse 将行值与我创建的 header_suffix 匹配,这包含数据框 colnames 的后缀。

df <- read.table(header = T,
                 text = "ID Q4_1 Q4_2 Q4_3 Q4_4 Q4_5
1  4    3    1  NA  NA
2  1    3 NA  NA  NA
3  3    1    2  NA  NA
4  5  NA  NA  NA  NA")

header_suffix <- gsub("^.+_", "", grep("_", colnames(df), value = T))

header_suffix
#> [1] "1" "2" "3" "4" "5"

df2 <-
  cbind(df[, 1], 
        as.data.frame(
          do.call(
            rbind, 
            lapply(1:nrow(df), function(x) 
              ifelse(header_suffix %in% df[x, 2:ncol(df)], header_suffix, NA))
            )
          )
        )

colnames(df2) <- colnames(df)

df2
#>   ID Q4_1 Q4_2 Q4_3 Q4_4 Q4_5
#> 1  1    1 <NA>    3    4 <NA>
#> 2  2    1 <NA>    3 <NA> <NA>
#> 3  3    1    2    3 <NA> <NA>
#> 4  4 <NA> <NA> <NA> <NA>    5

reprex package (v2.0.1)

创建于 2022-03-31

这是一个 Tidyverse 方法

df %>% pivot_longer(2:6, names_to = "Q", values_to = "no") %>% 
  mutate(new_Q = paste0("Q4_", no)) %>% 
  filter(new_Q != "Q4_NA") %>% 
  select(ID, new_Q, no ) %>% 
  pivot_wider(id_cols = ID, names_from = new_Q, values_from = no) %>% 
  select(ID, Q4_1, Q4_2, Q4_3, Q4_4, Q4_5 )

# A tibble: 4 x 6
     ID  Q4_1  Q4_2  Q4_3  Q4_4  Q4_5
  <int> <int> <int> <int> <int> <int>
1     1     1    NA     3     4    NA
2     2     1    NA     3    NA    NA
3     3     1     2     3    NA    NA
4     4    NA    NA    NA    NA     5