将ifelse()与R结合使用并去除文本:如何处理NA值?

时间:2019-07-30 23:48:15

标签: r

我有一列包含混合单位的数据。我正在尝试使用ifelse()将分钟值标准化为小时,这是另一个单位。

以类似这样的数据开头:

test_df <- data.frame(
  median_playtime = c("2.5 hours", "9 minutes", "20 hours")
)

我正在尝试:

  test_df$median_playtime_hours <- ifelse(

  #if the data has hours in it, then...
  test = length(grep("hours", as.character(test_df$median_playtime) ,value=FALSE)) == 1

  #text removal if it contains hours
  ,as.numeric(gsub(pattern = " hours", replacement = "", x = as.character(test_df$median_playtime)))

  #otherwise, remove minutes text and divide by 60
  ,as.numeric(gsub(pattern = " minutes", replacement = "", x = test_df$median_playtime)) / 60
)

每条条件行都可以正常运行,但会为不匹配情况生成NA,因此最终结果是全面获得NA。有没有一种方法可以忽略NA或合并两个条件,所以NA并不是返回的唯一值?

2 个答案:

答案 0 :(得分:3)

您的test存在问题-它仅返回FALSE的单个值。如果您改用grepl进行测试,则会得到预期的结果:

test_df$median_playtime_hours <- ifelse(
    #if the data has hours in it, then...
    test = grepl("hours", as.character(test_df$median_playtime)),
    #text removal if it contains hours
    as.numeric(gsub(pattern = " hours", replacement = "", x = as.character(test_df$median_playtime))),
    #otherwise, remove minutes text and divide by 60
    as.numeric(gsub(pattern = " minutes", replacement = "", x = test_df$median_playtime)) / 60
)

答案 1 :(得分:2)

如果您将数字与单位分开,则查找表可以很好地工作:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.MainActivity">
    <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" tools:srcCompat="@tools:sample/avatars[0]"
            android:id="@+id/imageView"
            app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="120dp"
            android:layout_marginStart="120dp" app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginEnd="120dp"
            android:layout_marginRight="120dp" android:layout_marginTop="28dp"
            app:layout_constraintTop_toTopOf="parent" app:layout_constraintHorizontal_bias="0.497"
            android:layout_marginBottom="497dp" app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintVertical_bias="0.0"/>

    <TextView
            android:text="Get Rewarded with this"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:id="@+id/textView" android:layout_marginTop="8dp"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginEnd="32dp" android:layout_marginRight="32dp"
            app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="33dp"
            android:layout_marginStart="33dp"
            android:fontFamily="sans-serif-light" android:lineSpacingMultiplier="40"
            android:lineSpacingExtra="40sp"
            android:textSize="32dp"`enter code here`
            android:layout_marginBottom="378dp" app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/imageView"/>
</androidx.constraintlayout.widget.ConstraintLayout>

如果您想保留所有内容,

library(tidyverse)

test_df <- tibble(
    median_playtime = c("2.5 hours", "9 minutes", "20 hours")
)

test_df %>% 
    separate(median_playtime, c('time', 'units'), sep = '\\s', convert = TRUE) %>% 
    mutate(seconds = time *  c('minutes' = 60, 'hours' = 60*60)[units])
#> # A tibble: 3 x 3
#>    time units   seconds
#>   <dbl> <chr>     <dbl>
#> 1   2.5 hours      9000
#> 2   9   minutes     540
#> 3  20   hours     72000