【问题标题】:List operations on variables containing string列出对包含字符串的变量的操作
【发布时间】:2014-10-21 15:34:38
【问题描述】:

我不得不承认我完全被这个问题难住了,所以很抱歉没有明确的尝试,但希望我能清楚地问这个问题:

我有一个数据框列表。对于所有这些,有多个日期类型变量需要格式化为日期(例如,as.Date(data$var, format = "%m/%d/%y"))。

问题是日期变量在每个数据帧中的名称都不同。在下面的示例中,我们有“start_date”和“end_date”。

有没有办法编写一些对数据框中的变量名进行操作的函数,如果它找到包含“日期”的文本,是否会进行格式化操作?

数据框:

west <- data.frame(
    spend = sample(50:100,50,replace=T),
    trials = sample(100:200,50,replace=T),
    start_date = sample(c("06/07/14","06/08/14","06/09/14"), 50, replace=T),
    country = sample(c("usa","canada","uk"),50,replace = T)
    )

east <- data.frame(
    end_date = sample(c("06/07/14","06/08/14","06/09/14"), 50, replace=T),
    spend = sample(50:100,50,replace=T),
    trials = sample(100:200,50,replace=T),
    country = sample(c("china","japan","skorea"),50,replace = T)
    )

然后将它们变成一个列表(实际上,这是一个更大的列表):

combined <- c(west,east)

我如何从 grepl 语句中获取逻辑向量并告诉它对列表元素中逻辑向量为“TRUE”的变量进行操作?

grepl("date", names(combined))

[1] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE

【问题讨论】:

  • 您可以创建一个列表list(west, east) 并在该列表上应用grepl
  • @akrun 确实,OP 可以创建一个列表(确实应该,而不是 c(west, east),它不是数据框列表),但应用 @该列表中的 987654327@ 不起作用。
  • 是的。我建议将其发布为答案。

标签: r


【解决方案1】:

试试

lst1 <- lapply(list(west, east), function(x) {
            indx <- grepl("date", names(x))
            x[,indx] <- as.Date(x[,indx], format="%m/%d/%y")
            x
      })

如果您需要更新单个对象,即。 eastwest 等(这不是必需的,因为大多数操作,包括使用 write.csv/write.table 将其保存到文件中都可以使用 lapply 在列表中完成)

list2env(setNames(lst1, c("west", "east")), envir=.GlobalEnv) 

更新

如果有多个变量带有date

east <- data.frame( end_date = sample(c("06/07/14","06/08/14","06/09/14"), 50,
replace=T), new_date = sample(c("06/07/14","06/12/14","06/09/14"), 50,
replace=T),    spend = sample(50:100,50,replace=T), trials = 
sample(100:200,50,replace=T), country =
sample(c("china","japan","skorea"),50,replace = T)) 


lst2 <- lapply(list(west, east), function(x) {
                 indx <- grepl("date", names(x))
                 x[,indx] <- lapply(x[,indx,drop=FALSE], as.Date, format="%m/%d/%y")
                  x})

 lapply(lst2, head,2)
 #[[1]]
 #    spend trials start_date country
 #1    83    188 2014-06-09     usa
 #2    83    107 2014-06-08     usa

 #[[2]]
 #   end_date   new_date spend trials country
 #1 2014-06-08 2014-06-12    53    144   china
 #2 2014-06-08 2014-06-09   100    118   china

【讨论】:

  • 等等……如果有多个日期变量怎么办?说:东
  • @Marc Tulia 更新了解决方案。抱歉,我没有考虑同一数据集中的多个日期列。
  • 太棒了(我在询问时没有想到两个 col 名称的情况,我的错)。但是为什么我需要编写一个 if/else 语句来涵盖这两种情况,而不仅仅是使用 lapply 语句呢?我认为您的第一个“if”场景中的 lapply 将涵盖 sum(indx) == 1 的特殊情况?我尝试并收到警告消息:“在[&lt;-.data.frame(*tmp*, , indx, value = list(16228, 16228, : 提供了 50 个变量来替换 1 个变量”
  • @Marc Tulla 我刚刚通过删除if else 进行了更新。谢谢你这么问。不需要。
猜你喜欢
  • 2020-12-24
  • 2012-12-02
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
  • 2022-11-27
  • 1970-01-01
  • 2019-11-12
相关资源
最近更新 更多