R 遍历列表
R loop over a list
嗨,我是新来的,也是 R 的新手。
如果有人可以在这里帮助我,那就太好了。
我正在尝试制作一个 for 循环以获得所需的输出,但目前有点困难。
假设下面有一个table:
> d
names variables value
1 colour c(red, blue) 10
2 colour c(yellow, blue) 32
3 colour c(green, red, pink) 81
4 colour c(pink, purple) 14
5 shape c(circle, triangle) 5
6 shape c(rectangle) 31
7 .....
我想做的是创建一个 for 循环遍历每个名称的变量。
如果存在每个名称的目标变量,则将原始值设置为 0 并创建一个复制行,其值取原始值的负值。
例如,假设我们的颜色目标变量是 'red'。
我希望输出看起来像:
> d1
names variables value
1 colour c(red, blue) 0
2 colour c(yellow, blue) 32
3 colour c(green, red, pink) 0
4 colour c(pink, purple) 14
5 colour1 c(red, blue) -10
6 colour2 c(green, red, pink) -81
7 shape c(circle, triangle) 5
8 shape c(rectangle) 31
7 .....
我希望我说得有道理。
如有任何帮助或意见,我们将不胜感激。
谢谢!!
你可以用 tidyverse
:
- 首先我们使用
stringr
包中的 str_detect
(它在 tidyverse 中)来识别那些具有 red
ind 变量的行。
- 然后我们将 1 和 2 (=row_number) 添加到
names
并且将 value
乘以 -1 以获得负值。
- 我们使用
dplyr
包中的 bind_rows
(它在 tidyverse 中)绑定到原始数据帧。
- 然后我们使用
ifelse
语句将变量red的值设置为0(假设原始值> 0。
- 我们使用
as_tibble()
删除行名,最后 arrange
library(tidyverse)
df %>%
filter(str_detect(variables, "red")) %>%
mutate(names = paste0(names, row_number()),
value = value*-1) %>%
bind_rows(df) %>%
mutate(value = ifelse(str_detect(variables, "red") &
value > 0, 0, value)) %>%
as_tibble() %>%
arrange(names)
names variables value
<chr> <chr> <dbl>
1 colour c(red, blue) 0
2 colour c(yellow, blue) 32
3 colour c(green, red, pink) 0
4 colour c(pink, purple) 14
5 colour1 c(red, blue) -10
6 colour2 c(green, red, pink) -81
7 shape c(circle, triangle) 5
8 shape c(rectangle) 31
structure(list(names = c("colour", "colour", "colour", "colour",
"shape", "shape"), variables = c("c(red, blue)", "c(yellow, blue)",
"c(green, red, pink)", "c(pink, purple)", "c(circle, triangle)",
"c(rectangle)"), value = c(10L, 32L, 81L, 14L, 5L, 31L)), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6"))
这是一个仅使用 Base R 的解决方案,使用 TarJae 的数据构造,用于数据帧 x
:
# Create a vector with the row indeces that contain the target string:
target <- grep( 'red', x[ , 2 ] )
# Put these rows away in a separate data.frame:
stash <- x[ target, ]
# Set the value of the original rows to `0`
x[ target, 3 ] <- 0
# Set the values in the separated rows to their negative value
stash[ , 3 ] <- stash[ , 3 ] * -1
# Modify `names` as desired:
for( i in 1 : length( stash[ , 1 ] ) )
stash[ i, 1 ] <- paste( stash[ i, 1 ], i, sep = "" )
# Insert the modified data (supposes that the dataframe is expected
# to be sorted on the first column):
x <- rbind( x, stash )
x <- x[ order(x[ 1 ] ), ]
这给了你
> x
names variables value
1 colour c(red, blue) 0
2 colour c(yellow, blue) 32
3 colour c(green, red, pink) 0
4 colour c(pink, purple) 14
11 colour1 c(red, blue) -10
31 colour2 c(green, red, pink) -81
5 shape c(circle, triangle) 5
6 shape c(rectangle) 31
如果您将 'red'
替换为 'blue'
或 'rectangle'
,这同样有效。对于您评论中的扩展问题:可以创建一个带有目标的向量(例如 c( "red", "triangle" )
,然后遍历上面的代码,将每个输出写入一个列表。有关您所需输出的更多示例数据和信息将是不过需要。作为第一步,您可以尝试:
crit <- c( "rectangle", "red", "blue" ) # vector with target values
y <- list() # initialize receiving list
for( j in 1 : length( crit ) )
{
target <- grep( crit[ j ], x[ , 2 ] )
stash <- x[ target, ]
stash[ , 3 ] <- stash[ , 3 ] * -1
# Modify `names` as desired:
for( i in 1 : length( stash[ , 1 ] ) )
stash[ i, 1 ] <- paste( stash[ i, 1 ], ( 10 * i + j ), sep = "" )
# write to list element instead of overwriting original dataframe
y[[ j ]] <- rbind( x, stash )
y[[ j ]][ target, 3 ] <- 0 # Set the value of the original rows to `0`
y[[ j ]] <- y[[ j ]][ order( y[[ j ]][ 1 ] ), ]
# here, you have a list with individual dataframes for each target value
# you could merge into one joint dataframe with
z <- Reduce( function( x, y, ... ) merge( x, y, all = TRUE, ... ), y )
}
产生
> z
names variables value
1 colour c(green, red, pink) 0
2 colour c(green, red, pink) 81
3 colour c(pink, purple) 14
4 colour c(red, blue) 0
5 colour c(red, blue) 10
6 colour c(yellow, blue) 0
7 colour c(yellow, blue) 32
8 colour12 c(red, blue) -10
9 colour13 c(red, blue) -10
10 colour22 c(green, red, pink) -81
11 colour23 c(yellow, blue) -32
12 shape c(circle, triangle) 5
13 shape c(rectangle) 0
14 shape c(rectangle) 31
15 shape11 c(rectangle) -31
这可能是进一步工作的良好开端
嗨,我是新来的,也是 R 的新手。 如果有人可以在这里帮助我,那就太好了。 我正在尝试制作一个 for 循环以获得所需的输出,但目前有点困难。
假设下面有一个table:
> d
names variables value
1 colour c(red, blue) 10
2 colour c(yellow, blue) 32
3 colour c(green, red, pink) 81
4 colour c(pink, purple) 14
5 shape c(circle, triangle) 5
6 shape c(rectangle) 31
7 .....
我想做的是创建一个 for 循环遍历每个名称的变量。 如果存在每个名称的目标变量,则将原始值设置为 0 并创建一个复制行,其值取原始值的负值。
例如,假设我们的颜色目标变量是 'red'。 我希望输出看起来像:
> d1
names variables value
1 colour c(red, blue) 0
2 colour c(yellow, blue) 32
3 colour c(green, red, pink) 0
4 colour c(pink, purple) 14
5 colour1 c(red, blue) -10
6 colour2 c(green, red, pink) -81
7 shape c(circle, triangle) 5
8 shape c(rectangle) 31
7 .....
我希望我说得有道理。 如有任何帮助或意见,我们将不胜感激。
谢谢!!
你可以用 tidyverse
:
- 首先我们使用
stringr
包中的str_detect
(它在 tidyverse 中)来识别那些具有red
ind 变量的行。 - 然后我们将 1 和 2 (=row_number) 添加到
names
并且将value
乘以 -1 以获得负值。 - 我们使用
dplyr
包中的bind_rows
(它在 tidyverse 中)绑定到原始数据帧。 - 然后我们使用
ifelse
语句将变量red的值设置为0(假设原始值> 0。 - 我们使用
as_tibble()
删除行名,最后arrange
library(tidyverse)
df %>%
filter(str_detect(variables, "red")) %>%
mutate(names = paste0(names, row_number()),
value = value*-1) %>%
bind_rows(df) %>%
mutate(value = ifelse(str_detect(variables, "red") &
value > 0, 0, value)) %>%
as_tibble() %>%
arrange(names)
names variables value
<chr> <chr> <dbl>
1 colour c(red, blue) 0
2 colour c(yellow, blue) 32
3 colour c(green, red, pink) 0
4 colour c(pink, purple) 14
5 colour1 c(red, blue) -10
6 colour2 c(green, red, pink) -81
7 shape c(circle, triangle) 5
8 shape c(rectangle) 31
structure(list(names = c("colour", "colour", "colour", "colour",
"shape", "shape"), variables = c("c(red, blue)", "c(yellow, blue)",
"c(green, red, pink)", "c(pink, purple)", "c(circle, triangle)",
"c(rectangle)"), value = c(10L, 32L, 81L, 14L, 5L, 31L)), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6"))
这是一个仅使用 Base R 的解决方案,使用 TarJae 的数据构造,用于数据帧 x
:
# Create a vector with the row indeces that contain the target string:
target <- grep( 'red', x[ , 2 ] )
# Put these rows away in a separate data.frame:
stash <- x[ target, ]
# Set the value of the original rows to `0`
x[ target, 3 ] <- 0
# Set the values in the separated rows to their negative value
stash[ , 3 ] <- stash[ , 3 ] * -1
# Modify `names` as desired:
for( i in 1 : length( stash[ , 1 ] ) )
stash[ i, 1 ] <- paste( stash[ i, 1 ], i, sep = "" )
# Insert the modified data (supposes that the dataframe is expected
# to be sorted on the first column):
x <- rbind( x, stash )
x <- x[ order(x[ 1 ] ), ]
这给了你
> x
names variables value
1 colour c(red, blue) 0
2 colour c(yellow, blue) 32
3 colour c(green, red, pink) 0
4 colour c(pink, purple) 14
11 colour1 c(red, blue) -10
31 colour2 c(green, red, pink) -81
5 shape c(circle, triangle) 5
6 shape c(rectangle) 31
如果您将 'red'
替换为 'blue'
或 'rectangle'
,这同样有效。对于您评论中的扩展问题:可以创建一个带有目标的向量(例如 c( "red", "triangle" )
,然后遍历上面的代码,将每个输出写入一个列表。有关您所需输出的更多示例数据和信息将是不过需要。作为第一步,您可以尝试:
crit <- c( "rectangle", "red", "blue" ) # vector with target values
y <- list() # initialize receiving list
for( j in 1 : length( crit ) )
{
target <- grep( crit[ j ], x[ , 2 ] )
stash <- x[ target, ]
stash[ , 3 ] <- stash[ , 3 ] * -1
# Modify `names` as desired:
for( i in 1 : length( stash[ , 1 ] ) )
stash[ i, 1 ] <- paste( stash[ i, 1 ], ( 10 * i + j ), sep = "" )
# write to list element instead of overwriting original dataframe
y[[ j ]] <- rbind( x, stash )
y[[ j ]][ target, 3 ] <- 0 # Set the value of the original rows to `0`
y[[ j ]] <- y[[ j ]][ order( y[[ j ]][ 1 ] ), ]
# here, you have a list with individual dataframes for each target value
# you could merge into one joint dataframe with
z <- Reduce( function( x, y, ... ) merge( x, y, all = TRUE, ... ), y )
}
产生
> z
names variables value
1 colour c(green, red, pink) 0
2 colour c(green, red, pink) 81
3 colour c(pink, purple) 14
4 colour c(red, blue) 0
5 colour c(red, blue) 10
6 colour c(yellow, blue) 0
7 colour c(yellow, blue) 32
8 colour12 c(red, blue) -10
9 colour13 c(red, blue) -10
10 colour22 c(green, red, pink) -81
11 colour23 c(yellow, blue) -32
12 shape c(circle, triangle) 5
13 shape c(rectangle) 0
14 shape c(rectangle) 31
15 shape11 c(rectangle) -31
这可能是进一步工作的良好开端