r - lapply,ifelse并尝试比较一列中的行与上一行

时间:2017-08-30 21:52:54

标签: r if-statement lapply cbind

请原谅我试图在R中使用我的excel逻辑,但我似乎无法解决这个问题。在函数中,给定X我试图找出它之前的行是否具有更大的值或不使用简单的逻辑。如果是,则在新列中显示为"是"如果不是"不"。

以下是示例数据:

temp <- data
GetFUNC<- function(x){
         temp <- cbind(temp, NewCol = ifelse(temp[2:nrow(temp),8] > temp[1:(nrow(temp)-1),8], "yes","no"))
         write.csv(temp, file = paste0(x,".csv"))
}
lapply(example,GetFUNC)

这样你就可以看到第8列:

testdata$numbers
 [1] 32216510 10755328  8083097  6878500  8377025  6469979 10675856  8189887  5337239
[10]  5156737

错误:

Error in data.frame(..., check.names = FALSE) : 
  arguments imply differing number of rows: 11, 10

感谢您提供的任何见解!

2 个答案:

答案 0 :(得分:3)

有几个问题:

  • 您不需要lapply,因为您使用的所有操作都已经过矢量化。
  • :的绑定比-更紧密(请参阅?Syntax),因此1:(nrow(temp)-1表示(1:(nrow(temp))-1。你想要1:(nrow(temp)-1)例如,比较这些:

    3:5-1
    ## [1] 2 3 4
    
    (3:5) - 1   # same
    ## [1] 2 3 4
    
    3:(5-1)    # different
    ## [1] 3 4
    
  • 即使最后一个更正,您的ifelse表达式也会返回一个小于testdata中行数的向量。在开头添加NA。

1)假设输入数据帧为testdata并在最后的注释中定义,那就更好了:

transform(testdata, NewCol = c(NA, ifelse(diff(numbers) < 0, "yes", "no")))

,并提供:

    numbers NewCol
1  32216510   <NA>
2  10755328    yes
3   8083097    yes
4   6878500    yes
5   8377025     no
6   6469979    yes
7  10675856     no
8   8189887    yes
9   5337239    yes
10  5156737    yes

2)以上可能是您想要的,但这是在zoo包中使用rollapplyr的第二个解决方案。它需要一个长度为2的滚动窗口,并在每个填充第一个值的NA上执行差异。

library(zoo)

transform(testdata, New = ifelse(rollapplyr(numbers, 2, diff, fill = NA) < 0, "yes", "no"))

注意:可重复形式的输入testdata为:

testdata <- data.frame(numbers = c(32216510, 10755328, 8083097, 6878500, 
    8377025 , 6469979, 10675856, 8189887, 5337239, 5156737))

答案 1 :(得分:0)

以下是一个dplyr解决方案,使用lag查看上一行,mutate添加新列。

library(dplyr)
df1 <- data.frame(numbers = c(32216510, 10755328, 8083097, 6878500, 8377025,
                               6469979, 10675856, 8189887, 5337239, 5156737))

df1 %>% 
  mutate(NewCol = ifelse(lag(numbers) > numbers, "yes", "no"))

    numbers NewCol
1  32216510   <NA>
2  10755328    yes
3   8083097    yes
4   6878500    yes
5   8377025     no
6   6469979    yes
7  10675856     no
8   8189887    yes
9   5337239    yes
10  5156737    yes