如何在R中对每一列的所有行重复执行一个函数。

问题描述 投票:1回答:2

我有一个有150行值的df,我想让R对df中的每一行和每一列重复以下内容。

数据的例子

df <- data.frame('criteria1' = c('x','1', 'X', '', 'X'), "criteria2" = c('y','3', '', 'X', ''), "criteria3" = c('y','7', '', 'X', 'X'))

如果一行中出现了一个X,我想让函数从前两行中取值,然后用'='将它们粘贴在一起。下面的操作对于第一行来说是很好的。

df$criteria1 <- ifelse(df$criteria1 == 'X', paste(df$criteria1 [1], '=', df$criteria1 [2]),'')
head(df)

问题是,当我尝试对数据框中的所有colomns做这件事时

df[] <- lapply(df, function(x) ifelse(df$x== 'X', paste(x[1], '=', x[2]),''))

所有单元格都变成了NA。我已经尝试了上面不同版本的代码,但没有任何东西给出预期的输出,这就是。

head(data.frame('criteria1' = c('x','1', 'x=1', '', 'x=1'), "criteria2" = c('y','3', '', 'y=3', ''), "criteria3" = c('y','7', '', 'y=7', 'y=7')))

r dataframe apply lapply repeat
2个回答
2
投票

使用 sapply 而不是 lapply... 有很多参考文献来说明两者之间的区别,但我相信问题来自于ifelse适用于一个向量,而不是一个列表,所以你不能把它传递给lapply。

sapply(df, function(x) ifelse(x == 'X', paste(x[[1]], '=', x[[2]]),''))

2
投票

A dplyr 解决办法。

编辑:

根据 @Chuk P 的评论(见下文),以下是对答案的编辑。

 df %>% 
   mutate_all(~ifelse(.=="X",paste0(.[[1]],"=",.[[2]]),""))
  criteria1 criteria2 criteria3
1                              
2                              
3       x=1                    
4                 y=3       y=7
5       x=1                 y=7

这与下面的输出相当。

ifelse(df$criteria1 == 'X', paste(df$criteria1 [1], '=', df$criteria1 [2]),'')
[1] ""      ""      "x = 1" ""      "x = 1"

原始答案(见评论,答案留在这里是为了防止将来有用)

df %>% 
   mutate_all(~ifelse(.%in%c(letters,LETTERS),paste0(.,"=",.[grep("\\d",.)]),.))

或使用 dplyr >=0.8.89.9000。

df %>% 
  mutate(across(everything(),~ifelse(.%in%c(letters,LETTERS),
                                     paste0(.,"=",.[grep("\\d",.)]),.)))

结果:

   criteria1 criteria2 criteria3
    1       x=1       y=3       y=7
    2         1         3         7
    3       X=1                    
    4                 X=3       X=7
    5       X=1                 X=7

如果你想用空白代替。

 df %>% 
   mutate_all(~ifelse(.%in%c(letters),paste0(.,"=",.[grep("\\d",.)]),.[!.%in%LETTERS]))
  criteria1 criteria2 criteria3
1       x=1       y=3       y=7
2         1         3         7
3                              
4         x                   y
5         1         y         7

注意::

可能存在更简单的方法。这是为了增加答案的多样性。


1
投票

您需要使用 mapply 这里,即

df[] <- mapply(function(x, y)replace(x, x == 'X', y), df, paste(df[1,], df[2,], sep = '='))

其中给出:

  criteria1 criteria2 criteria3
1         x         y         y
2         1         3         7
3       x=1                    
4                 y=3       y=7
5       x=1                 y=7
© www.soinside.com 2019 - 2024. All rights reserved.