繁体   English   中英

从多列中仅获取值(非 0、非 NA)

[英]Getting only value (non-0, non-NA) from multiple columns

这是我的数据示例:

df <- data.frame(Timing1 = c("Before", NA, 0, 0, 0, "Before"),
                 Timing2 = c(NA, "During", 0, "During", 0, NA),
                 Timing3 = c(0, NA, "After", "After", NA, 0))

我想创建一个名为Timing_combined的新列,它仅从其他 3 列中获取字符串(非 NA、非 0)值,并忽略 NA 和 0。

我想要的输出是这样的:

 Timing1  Timing2    Timing3   Timing_combined
  Before     <NA>         0             Before
    <NA>   During      <NA>             During
       0        0     After              After
       0   During     After     During & After
       0        0      <NA>               <NA>
  Before     <NA>         0             Before

这是我到目前为止的代码:

df <- df %>% 
  mutate(Timing_combined = apply(., 1, function(x) unlist(paste(x[!is.na(x) & x != 0], sep=" & "))))

这让我很接近,但还没有完全到位。

我遇到的问题主要是:

  1. 没有字符串的行(即只有 NA 或 0)将在我的数据中作为character(0)而不是 NA
  2. 具有多个时间的行作为列表存储在我的数据框中, c("Before", "After")而不是打印为"Before & After" paste()似乎不起作用,但是当我取出它时,其他事情出错了。

我在正确的轨道上吗? 或者有没有其他方法可以更好地做到这一点? 我想避免编写嵌套的 for/if 循环!

奖金:

我觉得我不是很了解如何x在匿名function(x)apply()由R.正在评估是否在这一点就是BEING通过函数传递,就像一个计时每列df$Timing1 或者按行,比如df$Timing1[1] ,然后移动到df$Timing1[2]等? 因为我指定了MARGIN=1 如果有人能以愚蠢的方式向我解释这一点,我将不胜感激! 我的实际数据集比这更复杂,所以我需要更好地理解这一点,以便我可以将其推断并应用(非双关语)到我更广泛的背景中。

谢谢!

我们可以将 0 值转换为NA ,然后使用unite with na.rm = TRUE来删除NA值。

library(dplyr)
library(tidyr)

df %>%
  mutate(across(.fns = ~na_if(., 0))) %>%
  unite(Timing_combined, starts_with('Timing'), 
        na.rm = TRUE, remove = FALSE, sep = ' & ')

#  Timing_combined Timing1 Timing2 Timing3
#1          Before  Before    <NA>    <NA>
#2          During    <NA>  During    <NA>
#3           After    <NA>    <NA>   After
#4  During & After    <NA>  During   After
#5                    <NA>    <NA>    <NA>
#6          Before  Before    <NA>    <NA>

如果你想使用apply

df$Timing_combined <- apply(df, 1, function(x) 
                            paste0(x[!is.na(x) & x != 0], collapse = ' & '))

apply的匿名函数如何工作取决于您使用的MARGIN 这里我们传递MARGIN = 1意味着匿名函数中的第一次迭代x将是第一行。 对于第二个, x将是第二行,依此类推。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM