【问题标题】:How to use a for-loop to apply a function to specific values in a column in a dataframe如何使用 for 循环将函数应用于数据框中列中的特定值
【发布时间】:2020-05-02 03:34:13
【问题描述】:

我有一个数据框,其中一列包含两个事件之间的时间,以年表示。我想让 R 创建一个新列,其中包含值小于 1 年的观察值,以天数表示。

我尝试使用 lapply 来解决这个问题,但是 lapply 给出了一个矩阵作为一个值,这对我来说并不理想。我想为此使用 for 循环,但我对 for 循环的经验有限。

dataframe <- data.frame(id=c(1,2,3,4,5), 
             names=c('a','b','c','d','e'),
             time_in_years=c(5.81, 0.39, 5.66, 4.18, 0.16),
             other_variable=c(3,4,23,0.7,76)
)

我将如何构建一个 for 循环,该循环添加一个包含 0 到 1 乘以 365.25 之间的“time_in_years”值的列?谢谢!

【问题讨论】:

  • 你不需要循环,因为操作会被向量化。所以你可以做类似dataframe$newtime &lt;- with(dataframe, ifelse(time_in_years &lt; 1, time_in_years * 365.25, NA))的事情。
  • 为什么只有 0 和 1 之间的年份,您可以使用 time_in_days 创建一个新列,例如:dataframe$time_in_days &lt;- dataframe$time_in_years * 365.25
  • @ulfelder 谢谢!这真的很好用,而且是一行简单的代码。

标签: r function dataframe for-loop


【解决方案1】:

这是使用 ifelse() 的基本 R 解决方案

dataframe <- within(dataframe, days <- 365.25*ifelse(time_in_years<1, time_in_years,NA))

这样

> dataframe
  id names time_in_years other_variable     days
1  1     a          5.81            3.0       NA
2  2     b          0.39            4.0 142.4475
3  3     c          5.66           23.0       NA
4  4     d          4.18            0.7       NA
5  5     e          0.16           76.0  58.4400

【讨论】:

  • 您的输出与您的(正确)代码不匹配,请更正输出,这可能会产生误导。
  • @RuiBarradas-ReinstateMonic 抱歉,我粘贴了错误的输出。现在它是固定的
【解决方案2】:

我喜欢data.table 的一点是,在这种情况下你不需要ifelse:

library(data.table)
datatable <- setDT(dataframe)
datatable[time_in_years<1,days := time_in_years*365.25]

   id names time_in_years other_variable     days
1:  1     a          5.81            3.0       NA
2:  2     b          0.39            4.0 142.4475
3:  3     c          5.66           23.0       NA
4:  4     d          4.18            0.7       NA
5:  5     e          0.16           76.0  58.4400

您也可以使用filter 并加入dplyr:

dataframe %>%
  filter(time_in_years < 1) %>%
  mutate(days = time_in_years * 365.25) %>%
  full_join(.,dataframe)

  id names time_in_years other_variable     days
1  2     b          0.39            4.0 142.4475
2  5     e          0.16           76.0  58.4400
3  1     a          5.81            3.0       NA
4  3     c          5.66           23.0       NA
5  4     d          4.18            0.7       NA

【讨论】:

  • 这是另一种方法!感谢您的贡献
【解决方案3】:

使用 dplyr 中的 mutate

你可以这样使用:

library(dplyr)
dataframe <- dataframe %>%
   mutate(days = ifelse(between(time_in_years, 0, 1), time_in_years * 365.25, NA))

> dataframe

   id names time_in_years other_variable   days
1  1     a          5.81            3.0       NA
2  2     b          0.39            4.0 142.4475
3  3     c          5.66           23.0       NA
4  4     d          4.18            0.7       NA
5  5     e          0.16           76.0  58.4400

没有外部库

如果你不想安装任何外部包,你可以使用这样的东西:

dataframe$time_in_days <- ifelse(dataframe$time_in_years > 0 & dataframe$time_in_years < 1, 
                                 dataframe$time_in_years * 365.25, 
                                 NA)

希望这会有所帮助。

【讨论】:

  • 感谢您的评论!它可以工作,但是它并没有明确地将新列添加到数据框中。您知道如何实现这一目标吗?
  • 谢谢,这是一个有效的解决方案!但是,我更喜欢不需要安装额外软件包的解决方案。
  • @Superschmiecht 不客气。我使用不需要任何外部包的解决方案更新了代码。希望这会有所帮助。
猜你喜欢
  • 2015-02-06
  • 1970-01-01
  • 2022-01-03
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-05
  • 2019-10-18
相关资源
最近更新 更多