【问题标题】:Using Conditional Statement to Evaluate Column, Calculate, and Create New Colum in Dataframe使用条件语句在 Dataframe 中评估列、计算和创建新列
【发布时间】:2021-08-24 22:49:44
【问题描述】:

我一直在使用 if/else if 语句的组合,但似乎无法获得预期的结果。我希望代码查看数据框topbottom 中的两列。如果其中一个数据缺失,则新列应等于不是0 的值。如果topbottom 值都存在,则应使用平均值填充该列。此外,如果两个值都是0,则新值也将是0

df$new <- if (df$top > 0 
            && df$bottom == 0){
            (df[["top"]])  
} else if (df$top == 0 
          && df$bottom > 0){
          (df[["bottom"]])  
} else if (df$top > 0 
          && df$bottom > 0){
          (df[["top"]] + df[["bottom"]])/2
}

目前,当我运行代码时,它正在创建一个新列 new,但只填充 (top + bottom)/2 值。

根据要求 df &lt;- data.frame(top = c(0, 2, 1, 4), bottom = c(1, 4, 0, 6))

然后输出...

       top  bottom  new
    1   0     1      1
    2   2     4      3
    3   1     0      1 
    4   4     6      5

【问题讨论】:

  • 你能发布想要的输出吗?
  • (1) 请分享您的数据示例,最好使用dput(head(df)) 和给定数据的您想要的输出。点击“编辑”按钮并将structure 输出放在那里。 (2) 在我看来,您正在寻找if 的矢量化版本。改用ifelse,或者,由于您使用多个条件,请尝试dplyrcase_when 函数。
  • 以上更新。抱歉,我对 R 很陌生。
  • "如果其中一个数据缺失,新列应该等于不为 0 的值" 如果顶部和底部缺失的值为 0 怎么办?应该分配什么?当您提到缺失值时,是指 NA 还是 0?
  • 我指的是0,所有NA's都已转换为0。至于topbottom 都等于0 时,0 的返回值就足够了,因此(top+bottom)/2 有效。

标签: r if-statement conditional-statements


【解决方案1】:

使用 ifelse&amp; 用于矢量化操作。 if&amp;&amp; 适用于单个值(第一个值),并且对数据的所有行重复相同的操作。

df <- transform(df, new = ifelse(top > 0 & bottom == 0, top, 
                        ifelse(top == 0 & bottom > 0, bottom, (top + bottom)/2)))
df

#  top bottom new
#1   0      1 1.0
#2   2      4 3.0
#3   0      0 0.0
#4   5      6 5.5

您也可以在此处使用dplyr 中的case_when -

library(dplyr)

df <- df %>%
  mutate(new = case_when(top > 0 & bottom == 0 ~ top, 
                         top == 0 & bottom > 0 ~ bottom, 
                         TRUE ~ (top + bottom)/2))

在真实数据上使用它我会首先使用janitor::clean_names() 来获得可以轻松引用的干净列名。然后你可以为新列实现case_when

Gagedf <- Gagedf %>%
  janitor::clean_names() %>%
  mutate(new = case_when(x_top_top_00095_00000 > 0 & x_bottom_bottom_00095_00000 == 0 ~ x_top_top_00095_00000, 
                         x_top_top_00095_00000 == 0 & x_bottom_bottom_00095_00000 > 0 ~ x_bottom_bottom_00095_00000, 
                         TRUE ~ (x_top_top_00095_00000 + x_bottom_bottom_00095_00000)/2))

【讨论】:

  • 我的列名标题可能有问题,我尝试了推荐的脚本但没有运气,还尝试重命名列标题以简化但没有运气。数据是从 USGS 网站下载的,所以我不确定是否存在问题。
  • 这些是我在下载过程中自动生成的实际列标题names(Gagedf) [1] "agency_cd" "site_no" "dateTime" [4] "X_TOP...Top._00095_00000" "X_TOP...Top._00095_00000_cd" "X_BOTTOM...Bottom._00095_00000" [7] "X_BOTTOM...Bottom._00095_00000_cd" "X_TOP...Top._00480_00000" "X_TOP...Top._00480_00000_cd" [10] "X_BOTTOM...Bottom._00480_00000" "X_BOTTOM...Bottom._00480_00000_cd" "tz_cd"
  • 嗯,您的实际数据中有多个顶部和底部列。样本数据只有一个。你想如何比较它们?您可以使用 dput(head(Gagedf)) 提供您的实际数据样本,并显示预期输出以明确问题。
  • 有多个 top 和 bottom 值,但是它们以特定的参数代码命名,即:X_TOP...Top._00095_00000,它们将与类似的参数进行比较。但是,我现在只看一个。为了简单起见,我尝试重命名列标题,但我似乎也做不到。
  • 这是您要找的吗? ```> dput(head(Gagedf))结构(列表(agency_cd = c(“USGS”,“USGS”,“USGS”,“USGS”,“USGS”,“USGS”),site_no = c(“301124081395901 ", "301124081395901", "301124081395901", "301124081395901", "301124081395901", "301124081395901" ), dateTime = structure(c(1514782800, 1514784600, 1514786400, 1514788200, 1514790000, 1514791800), class= c("POSIXct", "POSIXt" ), tzone = "UTC"), X_TOP...Top._00095_00000 = c(468, 469, 469, ```` 太长,无法全部显示
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-15
  • 2020-08-23
  • 2020-10-11
  • 1970-01-01
相关资源
最近更新 更多